How to: Restrict Access with the PrincipalPermissionAttribute Class

Controlling the access to resources on a Windows-domain computer is a basic security task. For example, only certain users should be able to view sensitive data, such as payroll information. This topic explains how to restrict access to a method by demanding that the user belong to a predefined group. For a working sample, see Authorizing Access to Service Operations.

The task consists of two separate procedures. The first creates the group and populates it with users. The second applies the PrincipalPermissionAttribute class to specify the group.

To create a Windows group

  1. Open the Computer Management console.

  2. In the left panel, click Local Users and Groups.

  3. Right-click Groups, and click New Group.

  4. In the Group Name box, type a name for the new group.

  5. In the Description box, type a description of the new group.

  6. Click the Add button to add new members to the group.

  7. If you have added yourself to the group and want to test the following code, you must log off the computer and log back on to be included in the group.

To demand user membership

  1. Open the Windows Communication Foundation (WCF) code file that contains the implemented service contract code. For more information about implementing a contract, see Implementing Service Contracts.

  2. Apply the PrincipalPermissionAttribute attribute to each method that must be restricted to a specific group. Set the Action property to Demand and the Role property to the name of the group. For example:

    // 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;
    }
    
    ' Only members of the CalculatorClients group can call this method.
    <PrincipalPermission(SecurityAction.Demand, Role:="CalculatorClients")> _
    Public Function Add(ByVal a As Double, ByVal b As Double) As Double
        Return a + b
    End Function
    
    

    Note

    If you apply the PrincipalPermissionAttribute attribute to a contract a SecurityException will be thrown. You can only apply the attribute at the method level.

Using a Certificate to Control Access to a Method

You can also use the PrincipalPermissionAttribute class to control access to a method if the client credential type is a certificate. To do this, you must have the certificate's subject and thumbprint.

To examine a certificate for its properties, see How to: View Certificates with the MMC Snap-in. To find the thumbprint value, see How to: Retrieve the Thumbprint of a Certificate.

To control access using a certificate

  1. Apply the PrincipalPermissionAttribute class to the method you want to restrict access to.

  2. Set the action of the attribute to SecurityAction.Demand.

  3. Set the Name property to a string that consists of the subject name and the certificate's thumbprint. Separate the two values with a semicolon and a space, as shown in the following example:

    // 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=ReplaceWithSubjectName; 123456712345677E8E230FDE624F841B1CE9D41E")]
    public double Multiply(double a, double b)
    {
        return a * b;
    }
    
    ' 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=ReplaceWithSubjectName; 123456712345677E8E230FDE624F841B1CE9D41E")> _
    Public Function Multiply(ByVal a As Double, ByVal b As Double) As Double
        Return a * b
    End Function
    
  4. Set the PrincipalPermissionMode property to UseAspNetRoles as shown in the following configuration example:

    <behaviors>  
      <serviceBehaviors>  
      <behavior name="SvcBehavior1">  
      <serviceAuthorization principalPermissionMode="UseAspNetRoles" />  
      </behavior>  
      </serviceBehaviors>  
    </behaviors>  
    

    Setting this value to UseAspNetRoles indicates that the Name property of the PrincipalPermissionAttribute will be used to perform a string comparison. When a certificate is used as a client credential, by default WCF concatenates the certificate common name and the thumbprint with a semicolon to create a unique value for the client's primary identity. With UseAspNetRoles set as the PrincipalPermissionMode on the service, this primary identity value is compared with the Name property value to determine the access rights of the user.

    Alternatively, when creating a self-hosted service, set the PrincipalPermissionMode property in code as shown in the following code:

    ServiceHost myServiceHost = new ServiceHost(typeof(Calculator), baseUri);
    ServiceAuthorizationBehavior myServiceBehavior =
        myServiceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
    myServiceBehavior.PrincipalPermissionMode =
        PrincipalPermissionMode.UseAspNetRoles;
    
    Dim myServiceBehavior As ServiceAuthorizationBehavior
    myServiceBehavior = _
       myServiceHost.Description.Behaviors.Find(Of ServiceAuthorizationBehavior)()
    myServiceBehavior.PrincipalPermissionMode = _
       PrincipalPermissionMode.UseAspNetRoles
    

See also