Monthly Archives: August 2008

WCF asynchronous processing and IIS hosting

Recommending the post “WCF Request Throttling and Server Scalability“.

It contains important information regarding WCF’s asynchronous processing when hosting on IIS. For example, I was unaware that

So in the release of .Net 3.0 and 3.5, WCF implemented synchronous versions of HTTP module and handler instead of asynchronous ones

meaning that even with asynchronous service implementation (asyncpattern=true), a thread will be blocked for the duration of the request’s processing. This thread will be the ASP.NET’s thread from the CLR ThreadPool.

Since I do most of my tests and experiences using self-hosting, I didn’t have noticed this.

However, the SP1 of .NET 3.5 adds support for asynchronous HTTP modules and handlers.

Using Zermatt’s claims model on WCF: ClaimsPrincipal.Current

In the last post, I briefly presented Zermatt’s claims model. This model can be used in both WCF based services or ASP.NET based web applications.

Beginning with this post, I will describe how this new claims model is integrated into WCF, using WCF’s extensibility points, and also what are some consequences of this integration.

Once again, keep in mind that these are empirical observations of the first beta release.

One way of using Zermatt’s claims model on a service, without needing to change WCF’s default behavior, is via the ClaimsPrincipal.Current static property. In WCF, the getter method will first check if the incoming message properties (available in the current operation context) contains a property whose name is typeof(IClaimsIdentity).FullName. If not, the getter method will create and return a ClaimsPrincipal instance based on the following procedure:

 

ClaimsPrincipal.Current

  1. Retrieves all the IAuthorizationPolicy objects from the current operation context.
  2. Creates a default AuthorizationContext with the claim sets produced by the evaluation of the above IAuthorizationPolicy set.
  3. Creates one ClaimsIdentity instance for each ClaimSet in the above AuthorizationContext. This ClaimsIdentity instance will contain one claim for each claim in the claim set whose with right equals Rights.PossessProperty (this means that claims with right = Rights.Identity will not be reflected in Zermatt’s claims model).
  4. Creates one ClaimsPrincipal referring the above ClaimsIdentity collection.

 

Before returning, the property’s getter method also adds the created ClaimsPrincipal instance to the incoming message properties, so that subsequent calls will simply return this ClaimsPrincipal cached instance.

In other words, the IClaimsPrincipal returned by ClaimsPrincipal.Current represents a view, using the “new” Zermatt’s claims model, of the “old” (System.IdentityModel) claims model.

Note however that this IClaimsPrincipal must be explicitly requested and is not referenced by Thread.CurrentPrincipal neither by ServiceSecurityContext.PrimaryIdentity.

 

Comments?

Zermatt’s claims model

In the last couple of posts, I’ve written about the claims and security token concepts, and also about how WCF models them:

In this post I will start writing about how these concepts are modeled in Zermatt:

The Microsoft Code Name “Zermatt” is a framework targeted for .Net developers to help them to build claims-aware applications to address today’s application security requirements using a simplified model that is open and extensible and can improve security

Disclaimer: my conclusions and remarks are based solely on public documentation and on observing the code of the beta release, so use them at your own risk.

A new claims model

Zermatt introduces a new class model for claims, implemented in the Microsoft.IdentityModel namespace and depicted in the following figure

 

claims.new 

 

This new model extends the classical .NET model, based on the IPrincipal and IIdentity interfaces, by creating two specialized interfaces: IClaimsPrincipal and IClaimsIdentity

 

IClaimsIdentity

The IClaimsIdentity interface, derived from the .NET framework’s IIdentity interface, represents a claims-based identity. It contains the Claims property, that references a collection of claims.
A claim is represented by the Claim class, namely by three properties:

  • ClaimType (string) containing the claim’s type
  • Value (string) with the claim’s value
  • ValueType (string) with the claim’s value type

There are some differences in the representation of claims, when compared with the “older” System.IdentityModel model.

  • In the new model, a claim value is always represented by a string. When this value is not a string but a more structured object, then this object must be serialized into a string. The ValueType property contains the type of the value represented by the string in Value. The ClaimValuesTypes class contains a set of constants with the most commonly used claim value types (strings).
    The ClaimTypes class contains a set of constants with some used claim types (strings).
  • There is no equivalent to the Right property.
  • A claim also has the following two properties, of IClaimsIdentity type:
    • The Subject property references the IClaimsIdentity partially defined by the claim.
    • The Issuer property references the identity of the claim issuer
  • There is no claim set concept. Namely, in the “new” model, each claims points to its issuer, that is modeled as a IClaimsIdentity.

The NameClaimType property of IClaimsPricipal is used to define the value of the Name property (inherited from IIdentity): this value is the value of the claim whose type equals NameClaimType.
The RoleClaimsType property has a similar goal: it defines the types of claims that define roles. This is used by classes implementing the IClaimPrincipal interface.

Finally, the IClaimsIdentity also possesses a Delegate property, of type IClaimsIdentity. This property is used in delegation scenarios, and will be described in a future post.

 

IClaimsPrincipal
This new model also introduces the IClaimPrincipal as a specialization of the .NET framework’s IPrincipal interface. Namely, this new interface adds a Identities collection that references a set of IClaimIdentity.

Note that the base interface IPrincipal already had a Identity property. The new Identities property (plural) is need because a principal can be associated with several identities, e. g., on delegation scenarios.

The implementation of the IsInRole interface method should/can use the RoleClaimTypes property of the identities referenced by the Identities property.

ClaimsPrincipal

The Zermatt’s claims model also contains an implementation of IClaimsPrincipal, called ClaimsPrincipal, with a static Current property – the IClaimsPrincipal associated with the current context.

 

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

Authorization policies in WCF: from tokens to claim sets

In a previous post, I presented some classes for handling security tokens in WCF. This post describes the process that begins with the authentication of a token and ends with a collection of claim sets, available at the AuthorizationContext (see this previous post).

One of the classes referred in the last post is the SecurityTokenAuthenticator class, containing the following method

public ReadOnlyCollection<IAuthorizationPolicy> ValidateToken(
    SecurityToken token
)

This method “Authenticates the specified security token and returns the set of authorization policies for the security token

Surprisingly, this method does not return a set of claims. Instead it returns a collection of IAuthorizationPolicy.

What is an authorization policy?

An authorization policy defines a rule for adding claims to a claim evaluation context. More precisely, the IAuthorizationPolicy interface has an Evaluate method that receives an EvaluationContext.

IAuthorizationPolicy

This class represents the context on which the authorization policies are evaluated. It exposes a property with a read-only collection of claim sets – the claim sets previously added to the context – and a method to add claims sets to the context. So, an authentication policy, via the Evaluate method, conditionally adds claim sets into the context based on the claim sets already there. This conditional addition can be used to implement claim normalization or claim inference policies.

An example of claim normalization is a policy that adds the claim “Teacher of X” to the context if it contains the claims “Professor of X” or “Teaching Assistant of X”. In this case, normalization means to represent a set of syntactically different (but semantically equal claims) by only one claim.

An example of claim inference is a policy that adds the claim “Authorized to post CS101 grades” if the context already contains the claim “Teacher of CS101”.

Unconditional policies

A particular case of policy is the unconditional authorization policy, i. e., a policy that always add the same claims sets to the evaluation context, independently of the claim sets already there. These are the type of authorization policy typically returned by token authenticators.

Policy evaluation process

The policy evaluation process uses policies from two origins:

  • Policies resulting from token authentication. These policies represent the claims issued to the message originator.
  • External policies, representing additional policy rules (e.g. normalization and inference rules).

IAuthorizationPolicy2

The claim sets resulting from the policy evaluation process are inserted into the AuthorizationContext.

Since there might be interdependencies between the policies, the policy evaluation process can call the Evaluate method of the same policy more than once. An example of interdependent policies is:

  • P1 (external policy): Add “Authorized to post CS101 grades” if “Teacher of CS101”.
  • P2 (external policy): Add “Teacher of CS101” if “Professor of CS101” or “Teaching Assistant of CS101”.
  • P3 (token policy): Add “Professor of CS101” unconditionally.

In this example, P2 must be evaluated after P3 adds the “Professor of CS101” claim, and P1 must be evaluated after P2 adds the “Teacher of CS101” claim. This results in more that one call to the Evaluate method, since there is no predefined order between the policies.

When a policy wants to be called again if additional claim sets are inserted by other policies, its Evaluate method must return false. If this method returns true, it means that no more claim sets will be added by the policy.

The policy evaluation process keeps repeatedly evaluating all the policies while

  • At least one policy returns false (meaning that it wants to be called again if new claim sets are added)
  • And the last policy evaluation cycle resulted in at least one new claim set added to the context.

If we model a authorization policy as a function mapping claim sets into claim sets, then the result of this evaluation process is the least fixed point of the policy set.

Security tokens in WCF

In WCF, security tokens are represented by classes derived from the SecurityToken abstract class. However, this class exposes little functionality:

  • A SecurityKeys property, to access the keys associated with this token.
  • Two properties, ValidFrom and ValidTo, with the token’s validity period.
  • A couple of methods for creating and matching key identifiers.

Most of the functionality related to security tokens is associated with three classes:

  • SecurityTokenProvider abstract class – Defines the interface for the creation of security tokens, i. e., for token factories. Typically, there is one concrete derived class for each token type (e. g. X509SecurityTokenProvider).
    Instances of classes derived from this one are used by the security protocol channel, at the message originator side, to create the tokens that are attached to the sent messages.

 

  • SecurityTokenSerializer abstract class – Defines the interface for serialization/deserialization into/from XML (XmlWriter/XmlReader) of token instances. The majority of token types are handled by the concrete WSSecurityTokenSerializer class.
    Instances with this type are used both at the message originator side and at the message recipient side.

 

  • SecurityTokenAuthenticator abstract class – Defines the interface for token verification and also for extracting the token’s claims. Typically, there is one concrete derived class for each token type (e. g. X509SecurityTokenAuthenticator).
    Instances with this type are used by the security protocol channel, at the message recipient side, to validate and extract the claims from the tokens attached to the received messages.

The figure below shows these classes, with some members hidden for legibility.

 

tokens

How are the provider/serializer/authenticator instances created?

The WCF runtime uses an object with type SecurityTokenManager (abstract class) to create a provider/serializer/authenticator instance, via the methods:

  • public abstract SecurityTokenProvider CreateSecurityTokenProvider(
        SecurityTokenRequirement tokenRequirement
    )
  • public abstract SecurityTokenSerializer CreateSecurityTokenSerializer(
        SecurityTokenVersion version
    )
  • public abstract SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(
        SecurityTokenRequirement tokenRequirement,
        out SecurityTokenResolver outOfBandTokenResolver
    )

How is the SecurityTokenManager instance created? 

Both the ClientCredentials and ServiceCredentials classes derives from the abstract class SecurityCredentialsManager, that contains a CreateSecurityTokenManager method.

Note that the ClientCredentials and ServiceCredentials classes hold the security configuration settings. These settings are reflected on the used token provider/serializer/authenticator via the chain of factories

  • ClientCredentials and ServiceCredentials creates SecurityTokenManager
  • SecurityTokenManager creates SecurityToken[Provider|Serializer|Authenticator]

token.factories


					

What are security tokens?

In the Identity Metasystem, claims are produced by issuers and consumed by relying parties (named service providers on other models). A security token is the data structure that holds the claims during the communication between these two parties. However, a security token is more that a mere container of claims. Typically, it contains the metadata required for two important functions:

  • Securely associate the contained claims with their issuer.
  • Securely bind the contained claims with the subject of these claims.

 

tokens

 

Typically, and for efficiency reasons, this metadata is not individually defined for each claim.

How are tokens associated with an issuer?

The association between a token and its issuer is normally (there are some exceptions) done using digital signatures: the token contains the signature of its content, verifiable using a key associated with the issuer (e.g. the issuer’s public key).

How is identified the subject of the claims?

The two commonly used methods for binding the claims to its subjects are:

  • Bearer – The holder of the token is the subject of the token’s claims. This is similar to the concept of bearer check. Namely, it has the same problems as bearer checks: anyone that gets the token can pretend to be the token subject.
  • Holder-of-key – The token claim’s subject is the entity that proves to possess a key specified in the token.

Associating tokens to messages

Security tokens are used to authenticate message originators, i.e., to obtain a claim set of which the message originator is the subject. Examples are:

  • Web applications: authenticate the HTTP request originator
  • Web services: authenticate the SOAP message originator

In the web applications context, the security token is simply added to the HTTP request (see the “A Guide to Using the Identity Selector Interoperability Profile V1.0 within Web Applications and Browsers” for an example). Since a typical browser does not have the ability to sign HTTP requests, the simpler (and more insecure) “Bearer” method is used.

In the web service context, the security token is added as an header of the SOAP message. In this case, the “Holder-of-key” method is used, implying that the SOAP message contains a signature verifiable with the key specified in the token. This cryptographic binding between the message originator and the token subject is defined by the WS-Security and WS-SecurityPolicy specifications.

Concrete token types

The Identity Metasystem does not define a specific token type. Neither do the WS-* specifications. Instead, these models aim to support different token types, namely tokens based on legacy mechanisms and protocols.

The OASIS Web Services Security standard defines several profiles describing how to use different security structures as security tokens, namely:

  • Kerberos tickets
  • X.509 certificates
  • SAML assertions
  • Username+password pairs