WCF Security – How do I restrict user access to methods in WCF?


Authentication verifies that a users is who he claims to be. This can be done in a couple of ways: certificates, username/password, windows credentials. Authorization will decide what an authenticated user is allowed to execute.

Implementing restricted access to WCF service can be done in a couple of ways:

Method 1: Mark methods with the declarative PrincipalPermissionAttribute to restrict access to certain roles or users.

Method 2: Imperatively check the credentials of the current user.

Method 3: Custom implementation of ServiceAuthorizationManager.

Method 1 & 2 have the drawback that they result in a lot of duplication when you have multiple service methods.

In WCF to implement authorization in a generic way the “ServiceAuthorizationManager” is used. The ServiceAuthorizationManager object is used to perform the access check and determine whether the claims associated with the client satisfy the requirements necessary to access the service method.

Let’s see some of the methods to restrict user access to some methods with examples.

Example 1: To restrict access of WCF service to users of the windows group “Administrators” using ServiceAuthorizationManager.

We need to override the method “CheckAccessCore” of ServiceAuthorizationManager class.


public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
    protected override bool CheckAccessCore(OperationContext operationContext)
    {
        try
        {
            ServiceSecurityContext securityContext = operationContext.ServiceSecurityContext;
            WindowsIdentity callingIdentity = securityContext.WindowsIdentity;

            WindowsPrincipal principal = new WindowsPrincipal(callingIdentity);
            return principal.IsInRole("Administrators");
        }
        catch (Exception)
        {
            return false;
        }
    }
}

Now that our custom ServiceAuthorizationManager has been implemented, we need to hook it into the WCF pipeline. The most easy way to do is, by using the web.config or app.config file.


<system.serviceModel>
    <!-- Define service and endpoints Here -->
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyServiceBehavior">
                <serviceAuthorization serviceAuthorizationManagerType="MyNamespace.MyServiceAuthorizationManager, MyAssembly" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

Example 2: Allow specific users to access few methods of WCF Service using ServiceAuthorizationManager.

In your custom Authorization class, you will have to override the CheckAccessCore method as shown below. In there you can check for the custom attribute [Note: Create custom attribute with whatever properties you want]

Decorate the relevant methods with your custom attribute rather than PrincipalPermission.

Now inspect the custom attribute and perform any functions. For example, if the custom attribute’s “AllowAll” flag is set, you might skip the role check. Otherwise, you might get the user’s windows identity and check they are in the particular role.


protected override bool CheckAccessCore(OperationContext operationContext)
{
        string action = operationContext.IncomingMessageHeaders.Action;
        DispatchOperation operation = operationContext.EndpointDispatcher.DispatchRuntime.Operations.FirstOrDefault(o => o.Action == action);
        Type hostType = operationContext.Host.Description.ServiceType;
        MethodInfo method = hostType.GetMethod(operation.Name);
        var myCustomAttributeOnMethod = method.GetCustomAttributes(true).Where(a => a.GetType() == typeof (MyCustomAttribute)).Cast<MyCustomAttribute>();
    .
    .
    .
}  

Example 3: Restrict access to WCF operations to specific Windows users using PrincipalPermission attribute?

Use 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 which you wish 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 be members of the CalculatorClients group.


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

Example 4: Restrict access to WCF operations to specific Windows users using PrincipalPermission attribute using a certificate

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.

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 Add(double a, double b)
{
    return a + b;
}

4. Set the PrincipalPermissionMode property to UseAspNetRoles as shown in the following configuration example:


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

Summary

From above all solutions, I feel ServiceAuthorizationManager is a clean way to implement authorization at the service level.

Happy Programming !!!

Jay Ganesh

Useful References:
http://pfelix.wordpress.com/2008/08/06/the-serviceauthorizationmanager-class-in-wcf/
http://msdn.microsoft.com/en-us/library/ms731200.aspx

Advertisements

One thought on “WCF Security – How do I restrict user access to methods in WCF?

  1. Pingback: “Article of the day” @ ASP.NET Microsoft Website for Dec 22 , 2014 | Ramani Sandeep's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s