Quick and easy user-level security checks

Source: Internet
Author: User
    • Codeproject
    • Download source files-65.3 KB
    • Download Demo project-88.8 KB

Introduction

This article presents a library that enables a programmer to store and retrieve security credentials from a back-end database. the classes in the Library also extend. net role-based authorization mechanism by introducing the concept of a "right ". A right is a low level security element that can be assigned to a role or an individual user. the Library has des a specialized principal class that allows these rights to be verified in much the same way that roles are today through the standard. net Security classes.

The library will work with any compatible. net Language, and may be used in thin-client (Asp. net) or thick-client environments. the Library also exports a simple interface for management users, roles, and rights. the database code is logically isolated from the rest of the library, so adapting things to work with other databases is very straightforward.

Using the code

The classes that are visible outside the Library include:

  • Securitymanager-Allows for authenticating a user based on a user-name and password.
  • Usermanager-Allows for creating and removing users from the database.
  • Rolemanager-Allows for creating and removing roles from the database.
  • Rightmanager-Allows for creating and removing rights from the database.
  • Userrightmanager-Allows for creating and removing associations between users and rights.
  • Userrolemanager-Allows for creating and removing associations between users and roles.
  • Rolerightmanager-Allows for creating and removing associations between roles and rights.
  • Customidentity-ImplementsIidentityAnd provides access to some additional user specific properties.
  • Customprincipal-ImplementsIprincipalAnd provides the ability to perform rights authorization.
  • Securityexception-Allows the library to signal errors that are specific to the library.
  • Securitydataexception-Allows the library to signal errors that are specific to the database access code.

The database is pretty simple, and includes des the following tables:

As you have probably figured out, I created the default database using Microsoft Access. remember, you can use any other kind of database by simply writing a bit of database code and modifying the application configuration file. in fact, I intend to write an article in the future that will describe just how to go about doing that.

For now, I will describe how to use the library by looking at how it interacts with the demonstration Application. the demo is certainly not going to win any UI design awards but it will allow you to play with the library.

The demo starts by prompting you for a user-name and password, like this:

This is not just for show, the credentials you provide determine what you will be allowed to do once you get into the demo. start by using 'admin' for a user-Name and leave the password blank. the main screen of the demo provided des a list of users. selecting a user from the list populates the tabs on the right. those tabs present the user properties, along with any roles and/or rights that have been associated with the user. you may use this demo to poke around and get a feel for the capabilities of the library.

If you like, you can log into the demo as something other than the administrator. for instance, logging in as 'user' (again no password), will restrict some of the things you are able to do in the application. after all, it wouldn't do at all to have unauthorized users changing your security settings-right?

There is a menu choice called 'smart gu' that looks like this:

Checking this menu creates some basic "intelligence" in the GUI that disables certain buttons whenever a user logs in that isn't a member of the 'admin' role. I added this feature because the library will throw security exceptions if a non 'admin' user attempts to perform certain actions. if you want to see these exceptions then turn the "smart Gui" feature off. just remember, the security exceptions are not bugs, they are deliberately thrown in order to prevent unauthorized users from making changes to the database.

Here is a quick list of the library features that require the current user to be In the 'admin' role:

    • Creating, deleting or updating a user-defined t for changing the password.
    • Creating, deleting or updating a role.
    • Creating, deleting or updating a right.
    • Changing the role associations for a user.
    • Changing the right associations for a user.
    • Changing the right associations for a role.

The Library requires the current user to be authenticated in order to change a user's password. in addition, if you are trying to change the password for a user other than yourself, you must be a member of the 'admin' role. everything else in the library may be saved med by any user.

Let's see how the demo interacts with the library. If you press the 'Add user' button, the following code is executed:

Collapse Copy code
Private Void_ Doadduser () {adduserform form =NewAdduserform ();If(Form. showdialog (This)! = Dialogresult. OK)Return; Usermanager. Create (Form. username, form. Password );}//End _ doadduser ()

TheUsermanager. CreateMethod creates a new row inCg_security_userTable, and returns the new identifier. that is all you need to do in order to create a new user. removing a user is just as easy; pressing the 'del user' button causes this code to be executed:

Collapse Copy code
Private Void_ Dodeluser (){//Get the current user index.IntUserindex = m_listboxusers.selectedindex;//Get the identifiers.IntUserid = (Int32) M_usertable.rows [userindex] ["User_id"]; Usermanager. Delete (userid );}//End _ dodeluser ()

TheUsermanager. DeleteMethod simply removes the row fromCg_security_user, Along with any associated rows in other tables. the other manager classes perform similar functions in their own respective areas. it really is pretty easy to use the library, so I won't bother detailing every method of every class.

Points of interest

I think the most interesting classes in the library areCustomidentityAndCustomprincipal. These classes shocould be the primary interface between your code and this library. Since these classes are derived fromIprincipalAndIidentityRespectively, you may use them in the same way you wowould a standard. net Security object. for those times when you want to use some other authentication scheme, you can still use this library, just use your current identity class to createCustomprincipalObject. Provided the user is in the database, everything shoshould still work correctly. I sometimes use this approach to give Windows users additional rights for my own devious purposes.

Just in case you are wondering, here is an example (again from the demo) of how to useCustomprincipalAndCustomidentityClasses in your application:

Collapse Copy code
 Private   Void Mainform_load ( Object Sender, system. eventargs e ){ Try { //  Prompt the user for credentials. Loginform = New Loginform (); //  Did the user fail to provide credentials?          If (Form. showdialog ( This )! = Dialogresult. OK ){This . Close (); Return ;} //  End if the user failed to login.          //  Did we fail to authenticate the credentials?          If (! Securitymanager. Authenticate (Form. username, form. Password) {MessageBox. Show ( "  Failed to authenticate the user! " ); This . Close (); Return ;} //  End if the credentials were not authenticated.         //  Set the default principal for the rest of the application. System. appdomain. currentdomain. setthreadprincipal ( New Customprincipal ( New Customidentity (Form. username )));} //  End try      Catch (Exception ex) {MessageBox. Show (ex. Message ); This . Close ();} //  End catch } //  End mainform_load () 

Once the principal is set,. net uses it just as it wocould any other principal. When you perform security checks in your code, simply check forCustomprincipalLike this (fromUsermanager. updatepasswordMethod ):

Collapse Copy code
 //  Check that the user is authenticated before we proceed.  If (! Thread. currentprincipal. Identity. isauthenticated) Throw   New Securityexception ( "  User must be authenticated" + " In order to perform this action! " ); //  If the calling application is using our identity class, then  //  We can perform some additional verification.  If (Thread. currentprincipal. Identity. authenticationtype = "  Custom" ){ //  Get the identity class. Customidentity identity = (customidentity) thread. currentprincipal. identity; //  If the user isn' t attempting to change their own password then we      // Shocould verify that they are acting as an administrator before we      //  Proceed.      If (Identity. userid! = Userid ){ //  Check the role of the user before we proceed.          If (! Thread. currentprincipal. isinrole ( "  Admin" )) Throw   New Securityexception ( "  User must be in the admin" + " Role to perform this action! " );} //  End if the user shoshould be an administrator. } //  End if we shoshould verify the identity/role of the user. 

Using the library to check for a user's rights cocould be done like this:

Collapse Copy code
Private Bool_ Checkright (StringRightname ){If(Thread. currentprincipal. Identity. authenticationtype! ="Custom")Return False; Customprincipal CP = (customproncipal) thread. currentprincipal;ReturnCP. isauthorized (rightname );}//End _ checkright ()
I demand to know my rights!

So, how do you know what rights a user will end up? Simple, begin by selecting a user, then answer these three questions:

    • What roles (if any) have been associated with the user?
    • What rights (if any) have been associated with those roles?
    • What rights (if any) have been specifically associated with the user?

the first and second questions are fairly straightforward, if you assign one or more roles to a user and those roles each have one or more rights assigned to them, then the rights assigned to the user will be the combination of the two lists. if you don't assign any roles to a user then they won't have any rights. if you don't assign any right to the roles then again the user wont have any rights.

The third question is a little trickier because rights that are associated directly with a user override any other setting. normally, you shoshould probably stick to assigning rights through role associations, but every now and then, you may come into SS users that defy your ability to categorize them into a predefined role. in that case, you can turn a right on or off for a user by creating an association at this level and then enabling or disabling the association. enabling it means the user will always have the associated right, disabling it means the user will never have the associated right.

Here is an example:

    • Let's say a user is a member of role 'A' and role 'B '.
    • Let's also say that role 'a 'has right '1', and role 'B' has right '2 '.
    • At this point, the rights for the user wocould be: '1' and '2 '.
    • If we then add a disabled association between the user and right '1', the rights for the user become '2 '.
    • If we go on to add an enabled association between the user and right '3', then the rights for the user become: '2' and '3 '.
Conclusion

I didn't get involved in the internals of the library much since it is mostly standard database code with some plumbing thrown in to provide logical isolation from the rest of the library. I will talk about library internals more when I discuss how to implement a data access library for SQL-server.

Until then, play around with the demo application and consider how you might use the library in your next project.

Have fun! : O)

History
    • Library version 2.4-Original release on codeproject.
    • Library version 2.5-various small fixes for things that escaped me when I created the original article.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.