ASP.NET 2.0 Security Practices - Authorization

From Guidance Share

Jump to: navigation, search

Contents

How to perform authorization in ASP.NET

After you authenticate the caller, you can authorize the user prior to performing restricted operations or accessing restricted resources. ASP.NET attaches a User object (which implements an IPrincipal interface) to the current HTTP context (HttpContext.User) and you use that as the basis for your authorization checks. Administrators can configure authorization in Web.config or you can authorize the caller programmatically in code. Authorization options include:

  • FileAuthorization. For file types mapped by IIS to the ASP.NET ISAPI extension (Aspnet_isapi.dll), automatic access checks are performed using the authenticated user's Windows access token (which may be IUSR_MACHINE for anonymous users) against the access control list (ACL) attached to the requested ASP.NET file. The FileAuthorizationModule class only performs access checks against the requested file. For example, if you request Default.aspx and it contains an embedded user control (Usercontrol.ascx), which in turn includes an image tag (pointing to Image.gif), the FileAuthorizationModule performs an access check for Default.aspx and Usercontrol.ascx, because these file types are mapped by IIS to the ASP.NET ISAPI extension. The FileAuthorizationModule does not perform a check for Image.gif, because this is a static file handled internally by IIS. However, because access checks for static files are performed by IIS, the authenticated user must still be granted read permission to the file with an appropriately configured ACL.
  • UrlAuthorization. By configuring the <authorization> element in Web.config, administrators can authorize the user held in the HttpContext.User object. You can authorize the user based on the user's name or based on the user's role membership. ASP.NET version 2.0 on Windows Server 2003 protects all files in a directory, even those not mapped to ASP.NET, such as .html, .gif, and .jpg files.
  • Role checks in code. You can call User.IsInRole or Roles.IsUserInRole methods for fine grained authorization logic in code. Alternatively, you can use PrincipalPermission demands to ensure that the caller is a specific identity or a member of a particular role.


For more information, see How to perform role-based authorization in code and How to configure URL authorization in Web.config in this topic.


How to perform role-based authorization in code

You can perform role-based authorization in code either by performing explicit role checks (User.IsInRole or Roles.IsUserInRole) or by using PrincipalPermission demands. You can do the latter either imperatively in the body of a method or declaratively by adding attributes to your classes and methods. You often need to perform role-based authorization in code when you need additional run-time variables to be able to construct the required authorization logic. For example, authorization might be dependent on a user being a member of the Manager role and a transaction amount not exceeding a particular limit.


To use explicit role checks:

  • Use the IPrincipal interface of the user object attached to the current HTTP request. This approach works with ASP.NET versions 1.0, 1.1 and 2.0.
    if(User.IsInRole("Manager"))
      // Perform restricted operation
    else
      // Return unauthorized access error
    
  • Alternatively, use Role Manager APIs introduced in ASP.NET version 2.0, which support a similar Roles.IsUserInRole method, as shown here.
    if(Roles.IsUserInRole("Manager"))
      // Perform restricted operation
    else
      // Return unauthorized access error
    

    The preceding code tests whether the currently authenticated user is a member of a particular role. You can also test whether any given user is a member of a role, as follows.

    if(Roles.IsUserInRole("Bob", "Manager"))
      // Perform restricted operation
    else
      // Return unauthorized access error
    
    Note To use the Role Manager API, you must enable the role manager feature and configure an appropriate role store. The following Web.config file configuration enables role manager and uses the built-in WindowsTokenRoleProvider. This provider is for use with Windows authentication, where Windows groups are used as roles.
    <roleManager enabled="true" defaultProvider="AspNetWindowsTokenRoleProvider" />
    


To use PrincipalPermission demands:

  • Construct a PrincipalPermission object and call its Demand method to perform authorization.
  • For fine grained authorization, call PrincipalPermission.Demand within code as shown here.
    // Imperative checks 
    PrincipalPermission permCheckUser = new PrincipalPermission("Bob", null);
    permCheckUser.Demand();
    
  • Alternatively, you can decorate your classes or methods with the PrincipalPermissionAttribute as shown here.
    [PrincipalPermission(SecurityAction.Demand, Role="Manager")]
    


The advantage of this approach is that the security requirements of your methods are visible to tools such as Permview.exe.


How to use role manager in ASP.NET

Role manager is new feature introduced in ASP.NET 2.0 for role-based authorization.


To use the role manager feature in an ASP.NET application, you need to do the following:

  1. Add a <roleManager> element beneath the <system.web> section of your application's Web.config file and enable role manager by setting its enabled attribute to true.
  2. Add a connection string to the <connectionStrings> section to point to your roles store. If you are using the AuthorizationStoreRoleProvider, this is an LDAP query string pointing to your Authorization Manager Policy store in Active Directory or ADAM. If you are using the SqlRoleProvider, this is a database connection string that points to your role store database.
  3. Configure the specific provider in the <roleManager> element in your application's Web.config file. The role manager system supports the following providers:
    • If your application roles are in an Authorization Manager Policy store in Active Directory or ADAM, use the AuthorizationStoreRoleProvider.
    • If your application roles are in a SQL Server database, use the SqlRoleProvider.
    • If your application uses Windows groups as roles, use the WindowsTokenRoleProvider. Note that this is recommended to be used with Windows Authentication only.
    • If your application roles are in a store other than those previously listed, create a custom roles provider inheriting RoleProvider base class.
  4. Set the defaultProvider attribute on the <roleManager> element to the chosen role provider.


To check roles and manage roles, use the Role Manager API (for example Roles.IsUserInRole and Roles.CreateRole). For more information, see How To: Use Role Manager in ASP.NET 2.0.


How to use Windows groups for role authorization

If you use Windows authentication, you can use the ASP.NET 2.0 Role Manager feature with the WindowsTokenRoleProvider for role-based authorization. In this scenario, Windows groups are used as roles.


Enable role manager by setting the enabled attribute on the <roleManager> element to 'true. Note that the Machine.config file contains a default configuration for a WindowsTokenRoleProvider instance named AspNetWindowsTokenRoleProvider. You can use this provider instance and set it as the default provider by modifying your Web.config file as follows.

<system.web>
    <roleManager enabled="true" 
        defaultProvider="AspNetWindowsTokenRoleProvider" />
</system.web>


To check role membership to authorize callers, use the Role Manager APIs such as IsUserInRole.

if(Roles.IsUserInRole("Readers")){};


As in ASP.NET version 1.1, you can also directly check role membership by using the authenticated user's Windows token. You can do this by using manual, imperative, and declarative role checks. For more information, see How to perform role-based authorization in code in this topic.


How to use Authorization Manager in ASP.NET

The Role Manager feature provides an AuthorizationStoreRoleProvider that uses the Windows Server 2003 Authorization Manager.


To use AuthorizationStoreRoleProvider:

  1. Create an Authorization Manager policy store in either Active Directory or ADAM and grant administrative or reader rights to your ASP.NET process account, such as the Network Service account.
  2. Enable role manager by setting the enabled attribute on the <roleManager> element to true.
  3. Configure a connection string containing an LDAP query to point to your Authorization Manager (AzMan) policy store.
  4. Configure the AuthorizationStoreRoleProvider in Web.config.
  5. Set the defaultProvider attribute to your provider instance.


A typical configuration is shown here.

<connectionStrings>
    <add name="AuthorizationServices" connectionString="msldap://myserver:389/CN=Store,OU=SecNetPartition,O=SecNet,C=US"/>
 </connectionStrings>
<system.web>
   ...
   <roleManager defaultProvider="AuthorizationStoreRoleProvider" enabled="true">
        <providers>
          <add name="AuthorizationStoreRoleProvider" 
               type="System.Web.Security.AuthorizationStoreRoleProvider" 
               connectionStringName="AuthorizationServices" 
               applicationName="SampleApplication" />
        </providers>
   </roleManager>
   ...
 </system.web>

If you use an Authorization Manager policy store in Active Directory, the Authorization Manager policy roles are different from the Windows groups you define in Active Directory.


Note that the AuthorizationStoreRoleProvider only exposes a subset of Authorization Manager's functionality. For example, you cannot use Authorization Manager's authorization business logic, such as tasks and operations. If you need to use tasks and operations you need to use COM interop and directly call members of the azroles 1.0 type library. For more information, see How To: Use Authorization Manager (AzMan) with ASP.NET 2.0 and How To: Use ADAM for Roles in ASP.NET 2.0.


How to cache roles in ASP.NET

If a user's browser accepts cookies, you can cache role information for that user in a cookie on the user's computer. On each page request, ASP.NET reads the role information for that user from the cookie. This can improve application performance by reducing the amount of communication required with the data source to retrieve role information. If the role information for a user is too long to store in a cookie, ASP.NET stores only the most recently used role information in the cookie and then looks up additional role information in the data source as and when required.


To configure and enable role caching, set cacheRoleInCookie to true on the <roleManager> element as shown here.

<roleManager enabled="true" 
        cacheRolesInCookie="true" 
        cookieName=".ASPXROLES" 
        cookieTimeout="30" 
        cookiePath="/" 
        cookieRequireSSL="false" 
        cookieSlidingExpiration="true" 
        cookieProtection="All" 
        defaultProvider="AspNetSqlRoleProvider" 
        createPersistentCookie="false" 
        maxCachedResults="25"/>


To secure the cookie, set the cookieProtection attribute to All, to ensure that the cookie is signed and encrypted. Set cookieRequireSSL to true to ensure that the cookie is only transmitted over HTTPS connections. Set createPersistentCookie to false to ensure the cookie is not persisted on the client's computer, and then use the cookieTimeout attribute to set a limited cookie expiration time.


How to configure URL authorization in Web.config

To configure URL authorization, use an <authorization> element in Web.config and specify which user and/or role names are allowed access to the current directory or the nominated directory or file. ASP.NET version 2.0 on Windows Server 2003 protects all files in a given directory, even those not mapped to ASP.NET, such as .html, .gif, and .jpg files.


Authorization settings in Web.config refer to all of the files in the current directory and all subdirectories unless a subdirectory contains its own Web.config with an <authorization> element. In this case, the settings in the subdirectory override the parent directory settings.


URL authorization can be used for both forms authentication and Windows authentication. In the case of Windows authentication, user names take the form "DomainName\WindowsUserName" and role names take the form "DomainName\WindowsGroupName". The local administrators group is referred to as "BUILTIN\Administrators". The local users group is referred to as "BUILTIN\Users". The following example shows Windows users and Windows roles.

<authorization>
  <allow users="DomainName\Bob, DomainName\Mary" />
  <allow roles="BUILTIN\Administrators, DomainName\Manager" />
  <deny users="*" />
</authorization>


The following example uses a custom role.

<authorization>
  <allow roles="Manager"/>
  <deny users="*"/>
</authorization>


To apply authorization rules to a specific file or folder, enclose the <authorization> element inside a <location> element as shown here.

<location path="Secure" >
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
</location>

This example denies access to unauthenticated users and forces a redirect to the login page that is specified on the <forms> element.


The following example shows how you can apply authorization to a specific file (Page.aspx).

<location path="page.aspx">
    <authorization>
        ...
    </authorization>
</location>

If necessary, you can apply different authorization rules for separate pages based on the identity, or more commonly, the role membership of the caller, by using multiple <authorization> elements within separate <location> elements.


How to lock authorization settings

Server administrators can lock authorization settings by using the <authorization> element in the machine-level Web.config file. This ensures that an individual application cannot override machine-level policy. To lock authorization settings, surround the <authorization> element inside a <location> element and set allowOverride="false" as shown here.

<location path="" allowOverride="false">
  <system.web>
     <authorization>
        <deny users="?" />
       <allow users="*" />
     </authorization>
  </system.web>
</location>

This example forces authenticated access.

Personal tools