Authorization

patterns & practices Developer Center

Authorizing users of your WCF applications helps in reducing the attack surface. You control authorization by using either resource-based or role-based authorization.

Use the following guidelines to choose an authorization strategy when implementing role-base authorization:

  • If you store role information in Windows groups, consider using the WCF PrincipalPermission attribute class for role authorization.
  • If you use ASP.NET roles, use the ASP.NET Role Manager for role authorization.
  • If you use Windows groups for authorization, use the ASP.NET role provider with AspNetWindowsTokenRoleProvider.
  • If you store role information in SQL Server, consider using the SQL Server role provider for role authorization.
  • If you store role information in ADAM, use the Authorization Manager role provider.
  • If you store role information in a custom store, create a custom authorization policy.
  • If you need to authorize access to WCF operations, use declarative authorization.
  • If you need to perform fine-grained authorization based on business logic, use imperative authorization.

Each of these guidelines is described in the following sections.

If you store role information in Windows groups, consider using the WCF PrincipalPermission attribute class for role authorization

If you are using Windows groups to store user roles, map your Windows groups to the WCF service methods by using the PrincipalPermission attribute. Incoming client username credentials will be mapped to associated Windows groups. Service method access will be granted to the user if the user is a member of the group associated with the method being called.

The following example demonstrates how the WCF service's Add method will only run for users belonging to the CalculatorClients Windows group:

// Only members of the CalculatorClients group can call this method.
[PrincipalPermission(SecurityAction.Demand, Role = "CalculatorClients")]
public double Add(double a, double b)
{
    return a + b;
}

Additional Resources

  • For more information on authorization, see Authorization.
  • For an authorization Q&A, see the Authorization section of WCF Security Questions and Answers.

If you use ASP.NET roles, use the ASP.NET Role Manager for role authorization

If you are using ASP.NET roles, leverage these roles in your WCF service by using the ASP.NET role manager. The role information can be stored in SQL Server, Windows Groups, or an Authorization Manager (AzMan) policy store in ADAM.

The ASP.NET role manager supports role creation and role management, and automatically performs role lookup for authenticated users.

Additional Resources

  • For more information on authorization, see Authorization.
  • For an authorization Q&A, see the Authorization section of WCF Security Questions and Answers.

If you use Windows groups for authorization, use the ASP.NET role provider with AspNetWindowsTokenRoleProvider

If you use Windows groups for authorization, consider using the ASP.NET role provider with the AspNetWindowsTokenRoleProvider name. This allows you to separate the design of the authorization from the implementation inside your service. If you decide to change the role provider, it will not affect the code needed to perform the authorization. Also consider doing imperative checks by using the role manager API instead of performing authorization checks with WindowsPrincipal.IsInrole.

The following configuration example shows how to configure AspNetWindowsTokenRoleProvider:

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

Configure the service behavior to use ASPNetRoles and the role provider.

…
<behaviors>
    <serviceBehaviors>
        <behavior name="BehaviorConfiguration">
            <serviceAuthorization principalPermissionMode="UseAspNetRoles"
                roleProviderName=" AspNetWindowsTokenRoleProvider " />
            <serviceMetadata />
        </behavior>
    </serviceBehaviors>
</behaviors>
…

The following code example shows how to perform the authorization check in code, using the role manager API:

if (Roles.IsUserInRole(@"accounting"))
{
   //authorized
}
else
{
   //authorization failed
}

Additional Resources

If you store role information in SQL Server, consider using the SQL Server role provider for role authorization

If you store role information in SQL Server, configure your application to use the SQL Server role provider for authorization. The role provider allows you to load the roles for users without writing and maintaining custom code.

The following steps show how to use the SQL Server role provider to provide role-based authorization:

  1. Enable the role provider as shown below and configure the connection string pointing to the role store in SQL Server:

    …
    <configuration>
    …
    <connectionStrings>
        <add name="MyLocalSQLServer"
             connectionString="Initial Catalog=aspnetdb;data source=Sqlserver;Integrated Security=SSPI;" />
         </connectionStrings>
    
    <system.web>
    <roleManager enabled="true" defaultProvider="MySqlRoleProvider" >
          <providers>
            <add name="MySqlRoleProvider"
                 connectionStringName="MyLocalSQLServer"
                 applicationName="MyAppName"
                 type="System.Web.Security.SqlRoleProvider" />
          </providers>
        </roleManager>
    …
    <system.web>
    
  2. Configure the service behavior. Set the principalPermissionMode attribute to UseAspNetRoles and the roleProviderName attribute to MySqlRoleProvider.

    …
    <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="BehaviorConfiguration">
              <serviceAuthorization principalPermissionMode="UseAspNetRoles"
                roleProviderName="MySqlRoleProvider" />          
             </behavior>
          </serviceBehaviors>
        </behaviors>
    <services>
        <service behaviorConfiguration=" BehaviorConfiguration " name="MyService">
          <endpoint binding="wsHttpBinding" bindingConfiguration=""
            name="httpsendpoint" contract="IMyService2" />
         </service>
      </services>
      </system.serviceModel>
    …
    

Additional Resources

  • For more information on authorization, see Authorization.
  • For an authorization Q&A, see the Authorization section of WCF Security Questions and Answers.

If you store role information in ADAM, use the Authorization Manager role provider

If your application stores role information in an Authorization Manager (AzMan) policy store in Active Directory Application Mode (ADAM), use the Authorization Manager role provider. Authorization Manager provides a Microsoft Management Console (MMC) snap-in for creating and managing roles and managing role membership for users.

Additional Resources

If you store role information in a custom store, create a custom authorization policy

If your application stores authorization data in a custom store such as a SQL Server database, create a custom authorization policy to authorize your users.

To create a custom authorization policy, you implement a class derived from IAuthorizationPolicy along with an Evaluate method that you can customize for your user authorization policy.

The Policy library is configured in the configuration file or in code. The following example configures the policy location in the configuration file:

<serviceAuthorization serviceAuthorizationManagerType="Microsoft.ServiceModel.Samples.MyServiceAuthorizationManager, service">
<!-- The serviceAuthorization behavior allows one to specify custom authorization policies. -->
<authorizationPolicies>
<add policyType="Microsoft.ServiceModel.Samples.CustomAuthorizationPolicy.MyAuthorizationPolicy, PolicyLibrary" />
</authorizationPolicies>
</serviceAuthorization>

Additional Resources

If you need to authorize access to WCF operations, use declarative authorization

You can add declarative authorization by specifying required access for a particular method declared as an attribute on the operation. Declarative authorization checks will work if you are using the ASP.NET role provider or Windows groups. Use imperative authorization if you need finer-grained authorization decisions based on business logic.

The following code example shows how to use the PrinciplePermission attribute to perform declarative authorization:

[PrincipalPermission(SecurityAction.Demand, Role = "accounting")]
public double Add(double a, double b)
{
    return a + b;
}

Additional Resources

  • For more information on authorization, see Authorization.
  • For an authorization Q&A, see the Authorization section of WCF Security Questions and Answers.

If you need to perform fine-grained authorization based on business logic, use imperative authorization

Use imperative role-based authorization when you need to make fine-grained authorization choices based on business logic, or when you require finer-grained access control beyond the level of a code method.

Imperative check using a Windows principal:

WindowsPrincipal myPrincipal = new WindowsPrincipal(ServiceSecurityContext.Current.WindowsIdentity);
if(myPrincipal.IsInRole(@"domain\Accounting"))
{
//authorized
}
else
{
//not authorized
}

Imperative check using the ASP.NET role provider:

if (Roles.IsUserInRole(@"accounting"))
{
//authorized
}
else
{
//authorization failed
}

Additional Resources

  • For more information on authorization, see Authorization.
  • For an authorization Q&A, see the Authorization section of WCF Security Questions and Answers.