Authorization

patterns & practices Developer Center

  • How do I decide on an authorization strategy in WCF?
  • What is the difference between resource-based, roles-based, and claims-based authorization?
  • How do I use Windows groups for role authorization in WCF?
  • How do I use the SQL Server role provider for ASP.NET role authorization in WCF?
  • How do I use the Windows Token role provider for ASP.NET role authorization in WCF?
  • How do I use the Authorization Store role provider for ASP.NET role authorization in WCF?
  • What is the difference between declarative and imperative roles authorization?
  • How do I restrict access to WCF operations to specific Windows users?
  • How do I associate roles with a certificate?
  • What is a service principal name (SPN)?
  • How do I create a service principal name (SPN)?

How do I decide on an authorization strategy in WCF?

Know your authorization options and choose the most appropriate for your scenario. First decide if you want to use resource-based or role-based authorization. Resource-based authorization uses ACLs on the resource to authorize the original caller. Role-based authorization allows you to authorize access to service operations or resources based on the group a user is in.

  • If you choose to use role-based authorization, you can store your roles in Windows groups or in ASP.NET roles.
  • If you are using Active Directory, consider using Windows groups based on ease of maintenance and the fact that you maintain both roles and credentials in the Active Directory store. If you are not using Active Directory, consider using ASP.NET roles and the ASP.NET Role Provider.

Your authorization strategy may also be influenced by your choice of authentication type:

Resource-based Authorization

  • If you are using certificate authentication, you will need to map certificates to Windows groups.

  • If you are using username authentication, you will need to perform protocol transition.

  • Windows authentication will work with resource-based authorization by default.

  • Basic authentication will work with resource-based authorization by default.

    Note

    You need to impersonate for resource-based authorization.

Role-based Authorization

  • If you are using certificate authentication, you will need to map certificates to Windows groups.
  • If you are using username authentication with Windows groups, you will need to perform protocol transition.
  • Username authentication will work with ASP.NET roles by default.
  • Windows authentication will work with Windows groups by default.
  • Basic authentication will work with Windows groups by default.

Additional Resources

What is the difference between resource-based, roles-based, and claims-based authorization?

Roles-based authorization is used to group users into groups (roles) and then set permissions on the role rather than on individual users. This eases management by allowing you to administer a smaller set of roles rather than a larger set of users.

Resource-based authorization sets permissions on the resource itself. For instance, you would set an access control list (ACL) on a Windows resource and then use the identity of the original caller to determine access rights to the resource. If you use resource-based authorization in WCF, you will need to impersonate the original caller through the application layer (e.g., ASP.NET application), through the WCF service layer, and to the business logic code that is accessing the file resource.

Claims-based authorization provides additional layers of abstraction on your authorization strategy to make it easier to separate your authorization rules from the mechanism you use for authorization and authentication. For instance, you could authenticate a user with a certificate or with username/password credentials and then pass that claim-set to the service to determine access to resources. You create authorization policies that are used to generate a claim-set based on the authentication evidence presented by the user (e.g., username and password, certificate, Kerberos). The claim-set is then used by your service to determine what resources the original caller can access.

Additional Resources

How do I use Windows groups for role authorization in WCF?

Map Windows groups to WCF service methods by using the WCF PrincipalPermission attribute. Incoming client username credentials will be mapped to the associated Windows group. Service method access will be granted to a user only if he or she is a member of the group associated with the service method being called.

The following example demonstrates how the WCF service “Add” 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

How do I use the SQL Server role provider for ASP.NET role authorization in WCF?

The SQL Server role provider is configured in the WCF service web.config file. User and role information are stored in the Aspnetdb database. Incoming client connections supply a username and password for each method call. The SQL Server role provider matches the client username/password combination to information in the Aspnetdb database and determines if the associated role matches the PrincipalPermission attribute role required in the method definition.

The following example configures the service to enable the SQL Server role provider:

    <!-- Configure the Sql Role Provider -->
    <roleManager enabled ="true" 
                 defaultProvider ="SqlRoleProvider" >
      <providers>
        <add name ="SqlRoleProvider" 
             type="System.Web.Security.SqlRoleProvider" 
             connectionStringName="SqlConn" 
             applicationName="MembershipAndRoleProviderSample"/>
      </providers>
    </roleManager>
    <!-- Configure role based authorization to use the Role Provider -->
    <serviceAuthorization principalPermissionMode ="UseAspNetRoles"
                          roleProviderName ="SqlRoleProvider" />

Service methods include a PrincipalPermission directive that specifies the required authorization access role required.

    [PrincipalPermission(SecurityAction.Demand, Role = "Registered Users")]
    public double Multiply(double n1, double n2)
      {
         double result = n1 * n2;
         return result;
      }

The following code shows how to do the authorization check-in code:

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

}

The following client connection supplies a username and password to call the method:

      // Set credentials to Alice
      client.ClientCredentials.UserName.UserName = "Alice";
      client.ClientCredentials.UserName.Password = "ecilA-123";

      // Call the Add service operation.
      double value1 = 100.00D;
      double value2 = 15.99D;
      double result = client.Multiply(value1, value2);

Additional Resources

How do I use the Windows Token role provider for ASP.NET role authorization in WCF?

If you use ASP.NET roles, 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. When using imperative checks, consider using the role syntax 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>

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

The following code shows how to do the authorization check-in code:

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

}

Additional Resources

How do I use the Authorization Store role provider for ASPNET role authorization in WCF?

You can integrate Authorization Manager (AzMan) into your WCF service to provide authorization for your users. Configure the Authorization Manager ASP.NET role provider for the application that is hosting the WCF service. By configuring the ASP.NET role manager to use the AuthorizationStoreRoleProvider, you can use the role management API against an AzMan policy store.

Like other ASP.NET role providers, the Authorization Manager ASP.NET role provider is configured by using the <providers> element. The following configuration example shows how to integrate Authorization Manager into a WCF service:

<system.web>
    <roleManager enabled="true" defaultProvider="AzManRoleProvider">
      <providers>
        <add name="AzManRoleProvider"
             type="System.Web.Security.AuthorizationStoreRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, publicKeyToken=b03f5f7f11d50a3a"
             connectionStringName="AzManPolicyStoreConnectionString" 
             applicationName="MyWCFService"/>
      </providers>
    </roleManager>
</system.web>

      <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="BehaviorConfiguration">
                    <serviceAuthorization principalPermissionMode="UseAspNetRoles"
                        roleProviderName="AzManRoleProvider" />
                    <serviceMetadata />
                </behavior>
            </serviceBehaviors>
       </behaviors>

Additional Resources

What is the difference between declarative and imperative roles authorization?

Imperative authorization supports fine-grained authorization choices based on business logic. Imperative roles-based authorization is written into your code and processed at run time. Imperative security is useful when the resource to be accessed or action to be performed is not known until run time, or when finer-grained access control beyond the level of a code method is required.

Declarative authorization can be added to application code at design time by specifying required access for a particular method or class declared as an attribute on the operation. Declarative roles-based authorization is best for authorizing access to WCF at the operation level. Declarative authorization can be added to application code at design time by specifying required access for a particular method or class declared as an attribute on the operation. Because attribute metadata is discoverable using reflection, it is easier to track the security principals that are allowed to access each method. Declarative authorization checks will work if you are using the ASP.NET role provider or Windows groups.

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;
}

The following is an example of an imperative check using the ASP.NET role provider:

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

}

Additional Resources

How do I restrict access to WCF operations to specific Windows users?

Perform the following steps to restrict access to specific Windows users:

  1. Open the Computer Management Windows applet.

  2. Create a Windows group that contains the specific Windows users to whom you want to give access. For example, a group can be called “CalculatorClients”.

  3. Configure your service to require ClientCredentialType = “Windows”. This will require clients to connect using Windows authentication.

  4. Configure your service methods with the PrincipalPermission attribute to require connecting users to be members of the CalculatorClients 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

How do I associate roles with a certificate?

Perform the following steps to associate roles with a certificate:

  1. Configure your service to require ClientCredentialType = “Certificate”. This will require clients to connect using certificate authentication.

  2. Configure clients to supply a certificate. The incoming client requests will contain a certificate name and a unique thumbprint ID that can be matched against the service method PrincipalPermission certificate name and thumbprint.

  3. Configure your service methods with the PrincipalPermission attribute that specifies the required certificate name and thumbprint. Only incoming requests that supply credentials that match the certificate will be allowed to access the method.

    // Only a client authenticated with a valid certificate that has the 
    // specified subject name and thumbprint can call this method.
    [PrincipalPermission(SecurityAction.Demand,
        Name = "CN=MyCertificate; 123456712345677E8E230FDE624F841B1CE9D41E")]
    public double Multiply(double a, double b)
    {
        return a * b;
    }
    

Additional Resources

What is a service principal name (SPN)?

A service principal name (SPN) is the name by which a client uniquely identifies an instance of a service. The Kerberos authentication service can use an SPN to authenticate a service. When a client wants to connect to a service, it locates an instance of the service, composes an SPN for that instance, connects to the service, and presents the SPN for the service to authenticate.

Additional Resources

How do I create a service principal name (SPN)?

You can use the Setspn.exe tool to associate an SPN with your service.

The following example creates an SPN that can be used to access the service. The service is named “CalcService,” the computer is named “ComputerA,” the domain is named “DomainA,” and the service account is the ASPNET account.

C:\ Setspn —A CalcService/ComputerA  DomainA\ASPNET

Additional Resources