.NET Framework Role-Based Security


.NET Framework role-based security is a key technology that is used to authorize a user 's actions in an application. Roles are often used to enforce business rules. For example, a financial application might allow only managers to perform monetary transfers that exceed a particular threshold.

Role-based security consists of the following elements:

  • Principals and identities

  • PrincipalPermission objects

  • Role-based security checks

  • URL authorization

Principals and Identities

Role-based security is implemented with Principal and Identity objects. The identity and role membership of the authenticated caller is exposed through a Principal object, which is attached to the current Web request. You can retrieve the object by using the HttpContext.Current.User property. If the caller is not required to authenticate with the application, for example, because the user is browsing a publicly accessible part of the site, the Principal object represents the anonymous Internet user.

There are many types of Principal objects and the precise type depends on the authentication mechanism used by the application. However, all Principal objects implement the System.Security.Principal.IPrincipal interface and they all maintain a list of roles of which the user is a member.

Principal objects also contain Identity objects, which include the user's name , together with flags that indicate the authentication type and whether or not the user has been authenticated. This allows you to distinguish between authenticated and anonymous users. There are different types of Identity objects, depending on the authentication type, although all implement the System.Security.Principal.IIdentity interface.

The following table shows the range of possible authentication types and the different types of Principal and Identity objects that ASP.NET Web applications use.

Table 6.1: Principal and Identity Objects Per Authentication Type

Authentication Type

Principal and Identity Type

Comments

Windows

WindowsPrincipal +

WindowsIdentity

Verification of credentials is automatic and uses the Security Accounts Manager (SAM) or Active Directory. Windows groups are used for roles.

Forms

GenericPrincipal +

FormsIdentity

You must add code to verify credentials and retrieve role membership from a user store.

Passport

GenericPrincipal +

PassportIdentity

Relies on the Microsoft Passport SDK. PassportIdentity provides access to the passport authentication ticket.

PrincipalPermission Objects

The PrincipalPermission object represents the identity and role that the current principal must have to execute code. PrincipalPermission objects can be used declaratively or imperatively in code.

Declarative Security

You can control precisely which users should be allowed to access a class or a method by adding a PrincipalPermissionAttribute to the class or method definition. A class-level attribute automatically applies to all class members unless it is overridden by a member-level attribute. The PrincipalPermissionAttribute type is defined within the System.Security.Permissions namespace.

Note  

You can also use the PrincipalPermissionAttribute to restrict access to structures and to other member types, such as properties and delegates.

The following example shows how to restrict access to a particular class to members of a Managers group . Note that this example assumes Windows authentication, where the format of the role name is in the format MachineName\RoleName or DomainName\RoleName . For other authentication types, the format of the role name is application specific and depends on the role-name strings held in the user store.

 [PrincipalPermissionAttribute(SecurityAction.Demand, Role=@"DOMAINNAME\Managers")] public sealed class OnlyManagersCanCallMe { } 
Note  

The trailing Attribute can be omitted from the attribute type names . This makes the attribute type name appear to be the same as the associated permission type name, which in this case is PrincipalPermission . They are distinct (but logically related ) types.

The next example shows how to restrict access to a particular method on a class. In this example, access is restricted to members of the local administrators group, which is identified by the special "BUILTIN\Administrators" identifier.

 [PrincipalPermissionAttribute(SecurityAction.Demand,                               Role=@"BUILTIN\Administrators")] public void SomeMethod() { } 

Other built-in Windows group names can be used by prefixing the group name with "BUILTIN\" (for example, "BUILTIN\Users" and "BUILTIN\Power Users" ).

Imperative Security

If method-level security is not granular enough for your security requirements, you can perform imperative security checks in code by using System.Security.Permissions.PrincipalPermission objects.

The following example shows imperative security syntax using a PrincipalPermission object.

 PrincipalPermission permCheck = new PrincipalPermission(                                     null, @"DomainName\WindowsGroup"); permCheck.Demand(); 

To avoid a local variable, the code above can also be written as:

 (new PrincipalPermission(null, @"DomainName\WindowsGroup")).Demand(); 

The code creates a PrincipalPermission object with a blank user name and a specified role name, and then calls the Demand method. This causes the common language runtime to interrogate the current Principal object that is attached to the current thread and check whether the associated identity is a member of the specified role. Because Windows authentication is used in this example, the role check uses a Windows group. If the current identity is not a member of the specified role, a SecurityException is thrown.

The following example shows how to restrict access to an individual user.

 (new PrincipalPermission(@"DOMAINNAME\James", null)).Demand(); 

Declarative vs. Imperative Security

You can use role-based security (and code access security) either declaratively using attributes or imperatively in code. Generally, declarative security offers the most benefits, although sometimes you must use imperative security (for example, when you need to use variables that are only available at runtime) to help make a security decision.

Advantages of Declarative Security

The main advantages of declarative security are the following:

  • It allows the administrator or assembly consumer to see precisely which security permissions that particular classes and methods must run. Tools such as permview .exe provide this information. Knowing this information at deployment time can help resolve security issues and it helps the administrator configure code access security policy.

  • It offers increased performance. Declarative demands are evaluated only once at load time. Imperative demands inside methods are evaluated each time the method that contains the demand is called.

  • Security attributes ensure that the permission demand is executed before any other code in the method has a chance to run. This eliminates potential bugs where security checks are performed too late.

  • Declarative checks at the class level apply to all class members. Imperative checks apply at the call site.

Advantages of Imperative Security

The main advantages of imperative security and the main reasons that you sometimes must use it are:

  • It allows you to dynamically shape the demand by using values only available at runtime.

  • It allows you to perform more granular authorization by implementing conditional logic in code.

Role-Based Security Checks

For fine-grained authorization decisions, you can also perform explicit role checks by using the IPrincipal.IsInRole method. The following example assumes Windows authentication, although the code would be very similar for Forms authentication, except that you would cast the User object to an object of the GenericPrincipal type.

 // Extract the authenticated user from the current HTTP context. // The User variable is equivalent to HttpContext.Current.User if you are using // an .aspx or .asmx page WindowsPrincipal authenticatedUser = User as WindowsPrincipal; if (null != authenticatedUser) {   // Note: If you need to authorize specific users based on their identity   // and not their role membership, you can retrieve the authenticated user's   // username with the following line of code (normally though, you should   // perform role-based authorization).   // string username = authenticatedUser.Identity.Name;       // Perform a role check   if (authenticatedUser.IsInRole(@"DomainName\Manager") )   {     // User is authorized to perform manager functionality   } } else {   // User is not authorized to perform manager functionality   // Throw a security exception } 

URL Authorization

Administrators can configure role-based security by using the <authorization> element in Machine.config or Web.config. This element configures the ASP.NET UrlAuthorizationModule , which uses the principal object attached to the current Web request in order to make authorization decisions.

The authorization element contains child <allow> and <deny> elements, which are used to determine which users or groups are allowed or denied access to specific directories or pages. Unless the <authorization> element is contained within a <location> element, the <authorization> element in Web.config controls access to the directory in which the Web.config file resides. This is normally the Web application's virtual root directory.

The following example from Web.config uses Windows authentication and allows Bob and Mary access but denies everyone else:

 <authorization>   <allow users="DomainName\Bob, DomainName\Mary" />   <deny users="*" /> </authorization> 

The following syntax and semantics apply to the configuration of the <authorization> element:

  • "*" refers to all identities.

  • "?" refers to unauthenticated identities (that is, the anonymous identity).

  • You do not need to impersonate for URL authorization to work.

  • Users and roles for URL authorization are determined by your authentication settings:

    • When you have <authentication mode="Windows" />, you are authorizing access to Windows user and group accounts.

      User names take the form " DomainName\WindowsUserName ".

      Role names take the form " DomainName\WindowsGroupName ".

      Note  

      The local administrators group is referred to as "BUILTIN\Administrators". The local users group is referred to as "BUILTIN\Users".

    • When you have <authentication mode="Forms" /> , you are authorizing against the user and roles for the IPrincipal object that was stored in the current HTTP context. For example, if you used Forms to authenticate users against a database, you will be authorizing against the roles retrieved from the database.

    • When you have <authentication mode="Passport" /> , you authorize against the Passport User ID (PUID) or roles retrieved from a store. For example, you can map a PUID to a particular account and set of roles stored in a Microsoft SQL Server database or Active Directory.

    • When you have <authentication mode="None" /> , you may not be performing authorization. "None" specifies that you do not want to perform any authentication or that you do not want to use any of the ASP.NET authentication modules, but you do want to use your own custom mechanism.

      However, if you use custom authentication, you should create an IPrincipal object with roles and store it in the HttpContext.Current.User property When you subsequently perform URL authorization, it is performed against the user and roles (no matter how they were retrieved) maintained in the IPrincipal object.

Configuring Access to a Specific File

To configure access to a specific file, place the <authorization> element inside a <location> element as shown below.

 <location path="somepage.aspx" />   <authorization>     <allow users="DomainName\Bob, DomainName\Mary" />     <deny users="*" />   </authorization> </location> 

You can also point the path attribute at a specific folder to apply access control to all the files in that particular folder. For more information about the <location> element, see Chapter 19, "Securing Your ASP.NET Application."




Improving Web Application Security. Threats and Countermeasures
Improving Web Application Security: Threats and Countermeasures
ISBN: 0735618429
EAN: 2147483647
Year: 2003
Pages: 613

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net