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
Open the Computer Management console.
In the left panel, click Local Users and Groups.
Right-click Groups, and click New Group.
In the Group Name box, type a name for the new group.
In the Description box, type a description of the new group.
Click the Add button to add new members to the group.
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
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.
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
Apply the PrincipalPermissionAttribute class to the method you want to restrict access to.
Set the action of the attribute to SecurityAction.Demand.
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
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 theName
property of thePrincipalPermissionAttribute
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. WithUseAspNetRoles
set as thePrincipalPermissionMode
on the service, this primary identity value is compared with theName
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