Exercise 1: Enabling claims based access for an ASP.NET Web Application by generating a local STS
Handling access control for a Web application is mainly a matter of handling three tasks:
In traditional development practice, you would implement those tasks by coding directly against the credentials that your application uses: that would require you to be skilled in security matters and would generate code that is difficult to maintain or re-host.
Windows Identity Foundation changes the game. As a first step, we externalize authentication. Instead of authenticating the users from our application, we trust an external authority to do so: we call such an authority Security Token Service, or STS. We configure our application to accept security tokens from the STS, transmitted using standard protocols. Those tokens are the proof that the user successfully authenticated with the STS, which is all we need for considering the user authenticated with our application: hence we don’t need to worry about managing credentials anymore. For this reason, it is common in the security jargon to call an application that accepts tokens from an STS relying party (or RP).
The security tokens can also contain information about users: we call those information claims. A claim can literally be anything: groups or roles the user belongs to, attributes like name or email, or permissions such as CanRead. The STS embeds in the token claims about the user at issuance time: the tokens are digitally signed, hence after issuance their values cannot be tampered with. If our application trusts the STS, it consider the claims in the tokens it produce as actually describing the user; as a result, our application no longer needs to look up user attributes for authorization or customization purposes.
If this all sounds a bit confusing, don’t worry: it will all become clear as we walk through the lab.
In this first exercise we will start from an existing ASP.NET application, which contains only some UI elements which need to be initialized with identity information about the current user. We will show how to secure the application and obtaining the identity info we need by taking advantage of a local STS. Since we don’t have a local STS available, we will create one: you’ll see how easy it is.
The redirects sequence and claims flow in the basic federation scenario implemented in exercise 1
Task 1 - Exploring the Initial Solution
Task 2 - Adding a Local STS to the Solution
Our website has no authentication code at all. As mentioned in the overview, we will outsource authentication to an STS we trust. In production we will have such an STS: but for now, there are none available. Fortunately, Windows Identity Foundation allows us to easily create local STSes that can be used for development purposes.
Task 3 - Adding Custom Claims
Task 4 - Using the Issued Claims
Task 5 - Verifying the Role Based Access
In order to verify current solution, proceed as follows:
Task 6 - Granting or Denying Access to the Website According to the User’s Age
In this task we are going to delete the ASP.NET Role settings and add a claims authorization manager to change the permissions criteria.
The fact that Windows Identity Foundation integrates well with existing authentication practices is a big advantage, since it allows you to protect existing skills and investments: however claims have much more expressive power than the classic roles and attributes, and can be used for achieving things that would have been impossible with traditional approaches. One simple example is using claims for expressing attributes that have non-string values, such as dates (date of birth, expiration date, etc), numbers (spending limit, weight, etc) or even structured data. Those data can be processed using criteria that are more sophisticated than the simple existence check (ie the user has claims A with value X, or he doesn’t): one example of such a criteria would be imposing that all the users of the website should be older than 21.The Windows Identity Foundation object model offers an extensibility point in the claims processing pipeline, which is specifically designed to allow you to inject your own claims authorization code. In order to do that, you are required to derive from the ClaimsAuthorizationManager class and implement your claim authorization logic in the method CheckAccess. It is common practice to express the authorization conditions outside of the code, for example in configuration files, and implement in CheckAccess generic evaluation logic so that the values & conditions can be changed at deployment time. This ensures that a change in the authorization conditions can be applied without recompiling anything. The conditions can be associated to the resources they refer to using some notation convention directly in the configuration files: however it is also possible to use explicit invocations from code, or decorating the resources themselves with attributes which will tie to authorization conditions and will fire the associated logic.In this task we are going to add a simple custom ClaimsAuthorizationManager whose only capability is making sure that only callers older than a certain threshold age are granted access to a given web resource.
Exercise 1: Verification
In order to verify that you have correctly performed all steps in exercise one, proceed as follows: