Introduction
As we know, Privilege control is a common and basic mechanism. People would be allocated into different access's roles, some of whom can maintain sensitive information based on their role, and the other cannot. It is the same as the computer world. For example, Microsoft Window, a famous PC OS, has a user management system in it, different users login with different access rights and operate different files or folders, the OS administrator can create different user accounts with different privileges. E.g., Ricky is an administrator and Jenny is a guest, both of whom launch the system based on their Login Name and Password. Ricky can control everything on the computer and Jenny does not have any permission except view right. In order to solve the complex cases, we need to develop a system to help us. It is also plain to see that the Privilege Right Control is a basic mechanism on top of the other systems.
Background
For Privilege Right Control is a basic mechanism, it should be implemented already. Many guys will have the following question "Why do you discuss here? Do you know to waste our times?". And the answer I want to say is "No". From experiences of many years, I have participated in developing many projects and most of those have its access right control except mini system. Take HR Management System as an example. HR Management System has a lot of sensitive information and there are many different modules in it, such as ESS (Employee self-service), Leave module, Payroll module, Attendance module, and so on. All of those modules should have access right controls. In the past, we used to create different access right control systems for different modules. That means if a user named Jenny should have more than five accounts for this HR Management System. It is not only hard for Jenny to remember these accounts but also hard to maintain. Furthermore, most of the existing systems do not cover all the real cases. E.g. Jenny is a sales manager, she can only access people under her team and she cannot access other team colleagues. So today, I introduce Cool Privilege Control for those who have the same questions as I met.
Cool Privilege Control I designed is used to centralize function's and user's operations and resolve different access levels problems. It looks like Single Sign On system and it is based on ASP.NET MVC, but it is not limited on web application only, since I split the solution into many tiers, UI (User Interface MVC), BL (Business Layer) and DAL (Data Access Layer). It is easy to replace UI from MVC to Window Application (WPF) and combine BL with DAL into WCF. And if you are a MVC developer, cool privilege control not only provides a single sign on solution to you, but also provides a prototype's scaffolding project to you.
Features
- Resolve normal access control issues (i.e., user and user role, function and function type)
- Resolve user with different organizations has different access levels problems
- Provide powerful audit log, trace log and exception log
- Easily and quickly create a prototype with privilege control and auto-generating menu
- Support multilingual
Look and Feel
First of all, I captured some screens of the application in order to increase study concentration.
Figure 4.1(Login Screen)
Figure 4.2(Function Management)
Figure 4.3(Edit Login User)
Figure 4.4(System Audit Log Management)
It is pretty cool, right? Thanks Bootstrap! That is a beautiful UI toolkit which helps developer to cut down lots of work! From now on, we will go a little deep to analyze all of scenarios about access control in real life.
Scenarios
5.1 Scenario 1
System has many functions, each function has many function types (i.e., insert
, update
, import
, export
and so on), which can be assigned to different functions, that means Function A has an import
method, Function B has an import
method as well. So the relationship between function and function type is many to many. It is easy to describe the entity relationship as the following diagram.
Figure 5.1.1 Function and Function Type relationship
Note: In the actual case, function structure maybe so complex. I used "000100010001
" format to separate function levels. For example, function path "0001
" indicates HR Module, there are many functions in it. Such as "00010001
" indicates Staff Info Management, "00010002
" indicates Salary Info Management, then "000100020001
" and "000100020002
" indicate Salary Info Maintenance and indicate Salary Review.
Figure 5.1.2 Functions Structure (HR Module)
Based on the format "000100020002
", we directly know the top menu which is named as "HR Module" by recursion. Each level has 9999 functions. Certainly, we can extend number length to increase function count for each level, if we use "000010000200002
" format instead of "000100020002
", then we can store 99999 functions for each level. The below figure shows what the menu looks like:
Figure 5.1.3 Menu (HR Module)
5.2 Scenario 2
Login user can be assigned to specific functions or specific roles. If a login user is assigned to multi roles, then the user can access all functions which are defined in those roles. That means Role A has access right on Function A, Role B has access right on Function B, if both Role A and Role B are assigned to a user named "Ricky
", then Ricky can access Function A and Function B. The below figure is the user-role entity relationship.
Figure 5.2.1 user-role relationship
5.3 Scenario 3
Each user can be assigned to one or more specific organizations, if you do that, he/she can only be allowed to access his/her subordinates information. To resolve these problems, we should create a new entity called "Organization Detail" which helps system to store privileges for organization assignment. That may not be easy to recognize. Take an actual case as an example which is easy to be recognized.
- A user named "
Angus
" and his business title is Project Manager and Sales Assistant Manager.
Assume the below settings.
Read-only right on function "Function Management".
Full access right on function "Login User Management" with Project Manager Level.
Read-only right on function "Login User Management" with Sales Assistant Manager Level.
- A user named "
Wells
" is a member of project team. - A user named "
Michael
" is a member of sales team.
Expect Result
When Angus logs into the system, he can access two functions, one is "Function Management" and the other is "Login User Management". According to the settings, Angus only has search right and view right on "Function Management". Meanwhile, On function "Login User Management", Angus can insert/update/delete user's records which are project team members, however, he cannot insert/update/delete user's records which are under sale team members except view and search.
According to the above case, we should set two organization details settings, the one is "ReadOnly
" and the other is "Login User Full Access". Below screens show organization details settings.
Figure 5.3.1 Function Detail Setting -- ReadOnly
Description: Organization Details named as "ReadOnly
" has "Search
" and "View
" on Function Management.
Description: Organization Details named as "ReadOnly
" only has "Search
" and "View
" on Login User Management.
Figure 5.3.2 Function Detail Setting -- Login User Full Privilege
Description: Organization Details named as "Login User Full Privilege" has full access right on Login User Management.
Figure 5.3.3 Login User Settings
Description: A login user named "Angus" is assigned to two organization settings
Project Team – Login User Full Access
Sales Team – ReadOnly
Figure 5.3.4.1 Organization Structure
Figure 5.3.4.2 Organization Structure Settings
Description: Previous organization settings use "000100010001
" format to present the organization structure.
Figure 5.3.5 Login User List (All Users)
After Angus logged in, he will see the following screens.
Figure 5.3.6 Function Management Screen
Description: All Edit/Delete buttons in the previous screen are dimed. Because "Angus
" only has view/search right on this function.
Figure 5.3.7 Login User Management Screen
Description: As the above screen described, both edit and delete button are dimmed, in which login name is Angus or Michael, because Angus cannot maintain the users under Sale Team Member and himself, but he can maintain the users under Project Team.
The below figure shows the ER diagram of the scenario:
Figure 5.3.6 Entity Relationship of Scenario
Settings
In order to fulfill MSSQL and MYSQL database developer, I publish two versions of the project. If you use MSSQL as default, please download "CoolAccessControl.Community.MYSQL.zip", otherwise, please download "CoolAccessControl.Community.MSSQL.zip". And I listed my development environment for your reference. If your local development environment is lower than mine, I suggest you upgrade the environment first so that you can run the program successfully. If your local version is equal to or above my development environment, there are no compatibility issues I trusted.
- Microsoft Visual Studio 2013
- .NET Framework 4.5.1
- MSSQL Server 2012 or MYSQL 5.6.26
- MVC 5.2.3
- Entity Framework 6.0
Mandatory Step: After opened solution, please right click solution and select "Enable NuGet Package Restore".
Figure 6.0.1 Enable NuGet Package Restore
6.1 EDIT WEB.CONFIG FILE
6.1.1 For MYSQL user
Figure 6.1.1 web.config(MySql Version)
Please pay attention to the appSettings
node, change DBSource
/DBName
/DBPort
/LoginName
/LoginPWD
value based on mysql server settings.
Property | Description |
DBSource | IP address of the server host |
DBName | Database name |
DBPort | Server TCP/IP port |
LoginName | DB user name |
LoginPWD | DB user password |
IsDebug | If you set true, all exceptions will be shown on the page, and vice versa |
6.1.2 For MSSQL user
Figure 6.1.2 web.config(MSSql Version)
The same as mysql user, change DBSource
/DBName
/LoginName
/LoginPWD
value based on mssql server settings, except DBPort
. In mssql server, the port number can be specified after the server name or server IP address with comma. For example:
WELLSCHEUNG\MSSQLSERVER2012,49287 49287 is the port.
Property | Description |
DBSource | IP address of the server host
With Port Format: server name or IP address, port
|
DBName | Database name |
LoginName | DB user name |
LoginPWD | DB user password |
IsDebug | If you set true , whatever exception will be show on the page, and vice versa. |
6.1.3 Enable or Disable DB Initializer
That is the feature of entity framework code first design pattern. And it is the most useful I have ever heard before. When you executed the project, if database instance did not exist in the server and the flag is enabled, entity framework would help you to initialize the db scheme. For more information, please refer to MSDN. If you do not want to initial database automatically and cover your database, you can set the attribute "disableDatabaseInitialization
" in context element to true
.
Figure 6.1.3 disableDatabaseInitialization flag
Alternative, you can initialize DB via SQL script or database backup. I prepare SQL script for mysql user to execute and database backup for mssql user to restore.
6.2 Edit Log4Net.config File
We use log4net to help us record the trace infos and the error infos. About how to use log4net, I thought most of you had more experiences than me, so I do not want to spend a lot of time on repeating. I only specified that all functions in the system enable trace log as default (i.e., include both input and output information). That is an easy way to trace error even if we cannot run Visual Studio debug when onsite support.
It is easy to turn off or change another types of information which you wanted to capture. There are seven levels type which were pre-setted in log4net.
The following levels were defined as an increasing priority order:
ALL
DEBUG
INFO
WARN
ERROR
FATAL
OFF
You can replace the value of the attribute "level
" to the above level in log4net.config.
Figure 6.2.1 Log4Net.config
SysLog : Log all info of the system |
ErrorLog : Only log exception of the system |
As mentioned before, previous settings will affect all the functions in the system. If you want to disable the logger individually. You can mark the function as "[UnTracerAction]
" function, then the function will not be traced.
Figure 6.2.2 UnTracerAction Function
If you only want to verify if the function is executed or not, except the detail information. You can mark the function as "[TracerActionWithDetails(EnableTracer=false)]"
function.
Figure 6.2.3 [TracerActionWithDetails(EnableTracer=false)] Function
The below capture screen demonstrates the result of previous different settings.
Figure 6.2.4 The log of tracer action without details
Figure 6.2.5 The log of tracer action with details
After previous settings, System is ready to use. Press "F5" in Visual Studio and double check if it has any compile errors or not. If any errors came out, you can send the error to me for inspection or search for the solution on Google by yourself.
In the next section, I will introduce functions in the system. Include create function types, create functions, create login users, create roles, create organizations, create access levels, assign functions to specific login user and so on.
How to Use
7.1 System Settings
- Click sub menu "System Info Management" in main menu "Access Management".
- Change values according to your requirement.
Key | Description |
Session Timeout(Seconds) | Default value is 10 mins = 600 seconds. Cool Privilege Control has a session management mechanism which is relayed on ASP.NET session management mechanism, that means, if you change the value to 20 mins or more than 20 mins, any session will only alive in 20 mins without user operation. Because the idle time is 20 mins by default in ASP.NET. If you want to set session timeout more than 20 mins, you must set the session timeout of ASP.NET bigger than session timeout of cool privilege control system. About how to change session timeout in ASP.NET, please refer to this link. I used to extend ASP.NET session timeout to 60 mins.
|
Page Size | Page size of each list page. |
Maximum Page Numbers Showing in Page Bar | Maximum Page Numbers Showing in Page Bar
|
Date Format | Default Format: yyyy-MM-dd. E.g. 2016-01-21 |
Time Format | Default Format: HH-mm-ss. E.g. 22:10:05 |
Password Policy | It contains many rules. I think it covers normal usage and I don’t want to spend a lot of time to explain each rule here. I trust all of you have the ability to understand the rule. |
7.2 Maintain Function Type
Cool Privilege Control allows user to create function type directly. View, Search, Create, Edit, Delete, Export, Import, Preview and Process are the most frequency function types. To avoid wasteful duplication of effort, System would add these function types after db was initialized.
-
Create Function Type
-
Click Create Function Type button at the bottom left of the Function Type Management page.
-
Type Function Type. Such as "Generate".
-
Click Save button.
-
Delete Function Type
Click Delete button of the record you wanted.
-
Edit Function Type
-
Click Edit
-
Change Function Type.
-
Click Save button.
7.3 Maintain Function
As section 5 described, Cool Privilege Control uses "000100010001
" format to separate functions. In theory, system supports unlimited function levels and 9999 functions for each function level.
-
Create Function
-
Click Create Function button in bottom left of the Function Management page.
-
Type Function Key and Function Path select Function Type which belongs to this function.
-
Click Save button.
-
Delete Function
Click Delete button of the record you wanted.
-
Edit Function
-
Click Edit button of the record you wanted.
-
Change value and Click Save button.
7.4 Maintain Role
-
Create Role
-
Click Create User Role button in bottom left of the Role Management page.
-
Type Role Name e.g., Admin
-
Assign Function with Function Type to the new role.
-
Click Save button.
-
Delete Role
Click Delete button of the record you wanted.
-
Edit Role
The steps are as the same as above section.
7.5 Maintain Organization
-
Create Organization
-
Click Create Organization button in bottom left of the Organization Management page.
-
Type Organization Key, e.g., CEO
-
Type Organization Path, e.g., 0001
-
Delete Organization (omitted)
-
Edit Organization (omitted)
7.6 Maintain Organization Details
-
Create Organization Details
-
Click Create Organization Details button in bottom left of the Organization Details Management page.
-
Type Organization Details Key.
-
Select Organization Details Type.
There are two types of organization details. One is "Specific Functions", the other is "As Role Settings". You can assign specific function into it, or set as role settings.
Figure 7.6.1 Specific Function
Figure 7.6.2 As Role Settings
-
Click Save button.
-
Delete Organization Details (Omitted)
-
Edit Organization Details (Omitted)
7.7 Maintain Login User
-
Create Login User
-
Click Create Login User button in bottom left of the Login User Management page.
-
Type mandatory fields. Such as Login Name / Password / Confirm Password / Status.
-
Select Login User Type.
-
Specific Functions: Assign specific functions to the user.
-
As Role Settings: Assign re-set roles to the user.
-
As Organization Settings: Assign organization unit with correlative organization details to the user.
-
Click Save button.
-
Delete Login User (Omitted)
-
Edit Login User (Omitted)
7.8 System Audit Log Management
In this function, you can retrieve all events recorded by system and filter what you want via selection criteria. More, you can export the log as Excel file for inspection.
7.9 Authorized History Management
7.10 Multilingual
As mentioned in the first section, Cool Privilege Control is based on multi language design pattern. Currently, there are three languages in the system. English, Simplified Chinese and Traditional Chinese. We can extend language package via add resource file. I hope you can help me to add more language package into the system. You can send your resource file to my email(wells-z@hotmail.com or wellscheung@gmail.com), I will consolidate all resource files and inject into the system. The following section will talk about how to create localized version of resource files.
7.10.1 Create localized version of resource files
-
Open project named "CoolAccessControlLangPack
".
We need to create three categories of resource files. There are FunctionRes.resx, lblCommon.resx and MsgRes.resx.
-
In Solution Explorer, right-click the project, point to Add, and then click New Item.
In the Add New Item dialog box, select Resources File and name the file FunctionRes.de-de.resx. The file name indicates the language, German, and the country, Germany.
File name format:
<language-country><base file name>.<language-country>.resx
If you do not know the country code and language code, please visit the link below:
http://www.csharp-examples.net/culture-names/
We have to create three files for each language and each country.
E.g.
-
FunctionRes.de-de.resx
-
lblCommon.de-de.resx
-
MsgRes.de-de.resx
-
Open Resource Designer, change Access Modifier to "No code generation" and copy all key-value pairs from base resource file to the new resource file.
-
Translate all sentences in Value column to your local language.
-
Save file and repeat the same action to create the remain files.
i.e., lblCommon.xx-xx.resx
MsgRes.xx-xx.resx
-
Send the above three files to me (wells-z@hotmail.com or wellscheung@gmail.com). And I will consolidate other guy's resources and publish a new version with your language pack to the site. Thank you.
Testing Site
For guys who wants to test the system immediately or traces bug, I created a testing site. Please visit http://www.wellscom.net. In order to protect our testing site, I have to lock the admin account and functions which function path starts with "0004
". And the site data will restore at midnight of American East.
I set up many accounts for you to test.
Admin -- Administrator
- Login Name: admin
- Password:123456
Angus – Project Manager
- Login Name: angus
- Password:123456
Wells – Project team developer
- Login Name: wells
- Password:123456
Alice – Project team officer
- Login Name: alice
- Password:123456
Tim – Sales Manager
- Login Name: tim
- Password:123456
Michael – Sales
- Login Name: michael
- Password:123456
Test-Driven Development
Cool Privilege Control System is using the test-driven development (TDD) approach. For many companys, TDD is a mandatory approach in repetition development cycle. Cool Privilege Control System contains 40 test cases in all Controllers, you can easily test all functions by clicking "Run All" in Test Explorer. Certainly, you can add new test case or add new conditions into the orignial test case based on your requirements. Cool Privilege Control System uses Xunit and Mock. Xunit is a test framework and is injected into Visual Studio, as the same as MSTest and Nunit. For more information, you can visit the official site.
Figure 6.0.1 Test Explorer
Finally
Cool Privilege Control is based on many interesting design patterns such as MVC, MEF, Entity Framework, jQuery and Bootstrap(UI). I am sorry I cannot introduce all of these design patterns to you in a short time. If you have any questions about Cool Privilege Control. Feel free and contact me. Thanks for your reading.
History
- 22nd January, 2016: Initial publication
- 1st February, 2016: Change project from "Cool Access Control" to "Cool Privilege Control", fixed bugs as well as display issue
- 2nd February, 2016: Fixed download link's destination
- 8th February, 2016: WCF Service preparation
- 1st March, 2016: Merge with WCF Service Version and add Testing project
- 18th July, 2016: Move the project to Github