The ServiceAuthorizationManager class in WCF

In the last post, I described the purpose of the IAuthorizationPolicy interface and the related policy evaluation process. In this post I will briefly described the classes involved in this process and how it can be customized.

The ServiceHostBase class contains the Authorization property, of type ServiceAuthorizationBehavior. This is the place where most of the authorization related service configuration is done. One of these configuration items is the ServiceAuthorizationManager that is used by the WCF runtime when dispatching a received message.

   1: public class ServiceAuthorizationManager
   2: {
   3:     public ServiceAuthorizationManager();
   4:     public virtual bool CheckAccess(OperationContext operationContext);
   5:     public virtual bool CheckAccess(OperationContext operationContext, ref Message message);
   6:     protected virtual bool CheckAccessCore(OperationContext operationContext);
   7:     protected virtual ReadOnlyCollection<IAuthorizationPolicy> GetAuthorizationPolicies(OperationContext operationContext);
   8: }

Note that the class is not sealed and the methods are virtual, meaning that a custom authorization manager can be used by creating a class derived from ServiceAuthorizationManager and assigning a instance of it to the ServiceAuthorizationBehavior.

One way of understanding the semantics of these methods is by analyzing how they are called by the WCF runtime. It all starts with the call of the CheckAccess method, that does the following:

  1. Calls the GetAuthorizationPolicies method to retrieve the collection with all the IAuthorizationPolicy objects. The base implementation of this last method retrieves both the token policies and external policies from the OperationContext
  2. Then, it creates a new ServiceSecurityContext, using the retrieved set of authorization policies, and assigns it to the property operationContext.IncomingMessageProperties.Security.ServiceSecurityContext.
    This ServiceSecurityContext has a property that returns a AuthorizationContext. Note that the AuthorizationContext is the container of all the claim sets (see this post for further information). 
  3. Finally, it returns the result of calling CheckAccessCore (which returns true by default).

The authorization policy evaluation process, described in the last post, is done the first time that the AuthorizationContext is retrieved from the ServiceSecurityContext.

Several customizations to the authorization manager can be made:

  • The simplest one is to override the CheckAccessCore method, inserting in it the authorization decision logic. Note that at this point, the resulting claim sets are already available and can be used by the authorization decision logic.
  • Another type of customization is to override the GetAuthorizationPolicies method. This can be useful to change the authorization polices that are used, e. g. , retrieve policies from an external policy store. As another example, this customization point is also used by Zermatt’s ExtensibleServiceCredentials.ConfigureServiceHost method.
  • Finally, the CheckAccess method can also be overridden, allowing for a complete change in the authorization process.

The next figure presents the majority of the classes involved in this process.

system.identitymodel

Advertisements

4 thoughts on “The ServiceAuthorizationManager class in WCF

  1. Nuno Monteiro

    Eng. Felix

    Se tiver tempo e se já tiver passado por isto pode ser que me consiga ajudar.

    Sucintamente. Eu crie uma custom IAuthorizationPolicy e uma custom ServiceAuthorizationManager no entanto ao contrário de tudo o que tenho lido, o framework WCF invoca primeiro os 2 métodos CheckAccess, o GetAuthorizationPolicies e o CheckAccessCore da classe CustomServiceAuthorizationManager e só depois o Evaluate da CustomAuthorizationPolicy.
    Logo não adianta usar o Evaluate para adicionar novos claims uma vez que os métodos CheckAccess já foram todos executados. Só estou a redefinir a implementação do CheckAccessCore.

    Se o Eng. Já passou por este problema e me conseguir ajudar agradeço, caso contrário agradeço na mesma 🙂

    Obrigado,

    Nuno Monteiro

    Reply
  2. Nuno Monteiro

    Resolvido. O Evaluate do IAuthorizationPolicy só é chamado quando acedemos à propriedade
    AuthorizationContext do tipo ServiceSecurityContext conforme descrito no post. Verifiquei esta situação com o Reflector.

    Código do tipo ServiceSecurityContext:

    public AuthorizationContext get_AuthorizationContext()
    {
    if (this.authorizationContext == null)
    {
    this.authorizationContext = AuthorizationContext.CreateDefaultAuthorizationContext(this.authorizationPolicies);
    }
    return this.authorizationContext;
    }

    internal static AuthorizationContext CreateDefaultAuthorizationContext(IList authorizationPolicies)
    {

    do
    {
    generation = evaluationContext.Generation;
    for (int i = 0; i < authorizationPolicies.Count; i++)
    {
    if (objArray[i] != obj2)
    {
    IAuthorizationPolicy policy = authorizationPolicies[i];
    if (policy == null)
    {
    objArray[i] = obj2;
    }
    else if (policy.Evaluate(evaluationContext, ref objArray[i]))
    {
    objArray[i] = obj2;
    if (DiagnosticUtility.ShouldTraceVerbose)
    {
    DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Verbose, TraceCode.AuthorizationPolicyEvaluated, SR.GetString(“AuthorizationPolicyEvaluated”, new object[] { policy.Id }));
    }
    }
    }
    }
    }
    while (generation < evaluationContext.Generation);

    }

    Obrigado.

    Reply
  3. Pingback: WCF Security – How Do I Restrict Access to some methods in WCF | Ramani Sandeep's Blog

  4. Pingback: WCF Security – How do I restrict user access to methods in WCF? « 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