MSDN Magazine - October 2008 - (Page 72) Figure 6 Claims Transformation Claims Transformation Service operations typically don’t care about the user’s SID or certificate thumbprint, but they do care about domain-specific identity information such as a user identifier, e-mail address, or purchase limit. Claims transformation is the process of transforming the technology-specific identity details into applicationspecific ones. Now that you have all identity information in a common format, it is easy to parse and analyze the claims information to create new claims that make more sense in the application context. Based on the identity claim of the WCF-generated claim set, you can map the request to an application user ID and add the relevant identity and authorization information to a new claim set. The service operation would then simply reach into the WCF authorization context to retrieve the information in which it is interested, as illustrated in Figure 6. Claims transformation is accomplished in an authorization policy. We have already used an authorization policy to create a custom principal, but this time it has a different purpose. Authorization policies can take part in the claims-generation process and run after the WCF internal claims generation is completed. That means the claims associated with the caller’s credentials are already accessible to you. You can query the existing claims for identity information and, based on that, create a new claim set that models your domainspecific claims. Then you can add it to the list of claim sets. This list will be used to create the authorization context before the request reaches the service operation. There are three members on the IAuthorizationPolicy interface that you have to implement. Id returns a unique identifier for the policy (usually a GUID), and Issuer returns a claim set describing the issuer of the claims that this policy creates. The most important method, however, is Evaluate. This method receives an evaluation context, which basically represents the authorization context while it is still in the process of being built. You get access to all currently generated claims via EvaluationContext.ClaimSets. Don’t try to touch the ServiceSecurityContext from within the Evaluate method, as this will trigger the authoriza72 msdn magazine tion policies again and you’ll end up in an infinite loop. You can add a new claim set to the evaluation context by calling EvaluationContext.AddClaimSet—this claim set will become part of the authorization context later on. Figure 7 shows a sample authorization policy that implements a common pattern. It first retrieves the identity claim of the first claim set. This claim is sent to a mapping component, which inspects the claim and returns an application user ID. After that the policy hits a data store using the ID to retrieve the information that should become part of the claim set. This information is then packaged as a new claim set and added to the evaluation context. The final step is to add the authorization policy to the serviceAuthorization behavior configuration. You can add multiple policies, and they are invoked in the order you add them. This means you can write multi-step authorization policies where one policy relies on values added by a previous one. This is pretty powerful for more complex scenarios: If you ran the previous code again to inspect the authorization context, you will see the new claim set and claims. The service operation would use similar code to check the claims for authorization (see Figure 8). The service authorization manager also works with claimsbased authorization. WCF passes the operation context into the CheckAccessCore method. From there you can reach into the service security context that will give you access to the authorization context. This allows you to centralize certain authorization decisions in a single place. Figure 7 An Authorization Policy class CustomerAuthorizationPolicy : IAuthorizationPolicy { Guid _id = Guid.NewGuid(); // custom issuer claim set ApplicationIssuerClaimSet _issuer = new ApplicationIssuerClaimSet(); public bool Evaluate(EvaluationContext evaluationContext, ref object state) { Claim id = evaluationContext.ClaimSets.FindIdentityClaim(); string userId = Map(id); evaluationContext.AddClaimSet(this, new CustomerClaimSet(userId)); } return true; public ClaimSet Issuer { get { return _issuer; } } public string Id { get { return ‘CustomerAuthorizationPolicy: ‘ + _id.ToString(); } } } Service Station
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.