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).
public ReadOnlyCollection<IAuthorizationPolicy> ValidateToken( SecurityToken token )
Surprisingly, this method does not return a set of claims. Instead it returns a collection of IAuthorizationPolicy.
What is an authorization policy?
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″.
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).
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.