Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Cool Privilege Control System Part 1 -- ASP.NET MVC

4.99/5 (84 votes)
18 Jul 2016Ms-PL18 min read 198.7K   3.5K  
Standalone Privilege Control, Single Sign-On Solution

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

  1. Resolve normal access control issues (i.e., user and user role, function and function type)
  2. Resolve user with different organizations has different access levels problems
  3. Provide powerful audit log, trace log and exception log
  4. Easily and quickly create a prototype with privilege control and auto-generating menu
  5. Support multilingual

Look and Feel

First of all, I captured some screens of the application in order to increase study concentration.

Image 1

Figure 4.1(Login Screen)

Image 2

Figure 4.2(Function Management)

Image 3

Figure 4.3(Edit Login User)

Image 4

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.

Image 5

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.

Image 6

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:

Image 7

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.

Image 8

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.

  1. 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.

  2. A user named "Wells" is a member of project team.
  3. 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.

Image 9

Figure 5.3.1 Function Detail Setting -- ReadOnly

Description: Organization Details named as "ReadOnly" has "Search" and "View" on Function Management.

Image 10

Description: Organization Details named as "ReadOnly" only has "Search" and "View" on Login User Management.

Image 11

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.

Image 12

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

Image 13

Figure 5.3.4.1 Organization Structure

Image 14

Figure 5.3.4.2 Organization Structure Settings

Description: Previous organization settings use "000100010001" format to present the organization structure.

Image 15

Figure 5.3.5 Login User List (All Users)

After Angus logged in, he will see the following screens.

Image 16

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.

Image 17

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:

Image 18

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.

  1. Microsoft Visual Studio 2013
  2. .NET Framework 4.5.1
  3. MSSQL Server 2012 or MYSQL 5.6.26
  4. MVC 5.2.3
  5. Entity Framework 6.0

Mandatory Step: After opened solution, please right click solution and select "Enable NuGet Package Restore".

Image 19

Figure 6.0.1 Enable NuGet Package Restore

6.1 EDIT WEB.CONFIG FILE

6.1.1 For MYSQL user

Image 20

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

Image 21

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.

Image 22

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.

Image 23

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.

Image 24

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.

Image 25

Figure 6.2.3 [TracerActionWithDetails(EnableTracer=false)] Function

The below capture screen demonstrates the result of previous different settings.

Image 26

Figure 6.2.4 The log of tracer action without details

Image 27

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

  1. Click sub menu "System Info Management" in main menu "Access Management".

    7.1.1

  2. Change values according to your requirement.

    7.1.2

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.

7.1.2.1

Page Size Page size of each list page.
Maximum Page Numbers Showing in Page Bar Maximum Page Numbers Showing in Page Bar

7.1.2.2

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.

  1. Create Function Type

    1. Click Create Function Type button at the bottom left of the Function Type Management page.

      7.2.1.1
    2. Type Function Type. Such as "Generate".

      7.2.1.2
    3. Click Save button.

  2. Delete Function Type

    Click Delete button of the record you wanted.

  3. Edit Function Type

    1. Click Edit

      7.2.1.3.1
    2. Change Function Type.

    3. 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.

  1. Create Function

    1. Click Create Function button in bottom left of the Function Management page.

      7.3.1.1
    2. Type Function Key and Function Path select Function Type which belongs to this function.

      7.3.1.2
    3. Click Save button.

      7.3.1.3
  2. Delete Function

    Click Delete button of the record you wanted.

  3. Edit Function

    1. Click Edit button of the record you wanted.

    2. Change value and Click Save button.

7.4 Maintain Role

  1. Create Role

    1. Click Create User Role button in bottom left of the Role Management page.

    2. Type Role Name e.g., Admin

    3. Assign Function with Function Type to the new role.

      7.4.1.3
    4. Click Save button.

  2. Delete Role

    Click Delete button of the record you wanted.

  3. Edit Role

    The steps are as the same as above section.

7.5 Maintain Organization

  1. Create Organization

    1. Click Create Organization button in bottom left of the Organization Management page.

    2. Type Organization Key, e.g., CEO

    3. Type Organization Path, e.g., 0001

      Image 39
  2. Delete Organization (omitted)

  3. Edit Organization (omitted)

7.6 Maintain Organization Details

  1. Create Organization Details

    1. Click Create Organization Details button in bottom left of the Organization Details Management page.

    2. Type Organization Details Key.

    3. 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.

      Image 40
      Figure 7.6.1 Specific Function
      Image 41
      Figure 7.6.2 As Role Settings
    4. Click Save button.

  2. Delete Organization Details (Omitted)

  3. Edit Organization Details (Omitted)

7.7 Maintain Login User

  1. Create Login User

    1. Click Create Login User button in bottom left of the Login User Management page.

      7.7.1.1
    2. Type mandatory fields. Such as Login Name / Password / Confirm Password / Status.

    3. Select Login User Type.

      1. Specific Functions: Assign specific functions to the user.

      2. As Role Settings: Assign re-set roles to the user.

      3. As Organization Settings: Assign organization unit with correlative organization details to the user.

        7.7.1.3
      4. Click Save button.

  2. Delete Login User (Omitted)

  3. 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.8

7.9 Authorized History Management

7.9

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

  1. Open project named "CoolAccessControlLangPack".

    7.10.1.1

    We need to create three categories of resource files. There are FunctionRes.resx, lblCommon.resx and MsgRes.resx.

  2. 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

      7.10.1.3
  3. 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.

    7.10.1.4
  4. Translate all sentences in Value column to your local language.

  5. Save file and repeat the same action to create the remain files.

    i.e., lblCommon.xx-xx.resx

    MsgRes.xx-xx.resx

    7.10.1.6
  6. 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.

Image 50

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

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)