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:
[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
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:
[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 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