If you’ve searched online for OAuth code, you’ll find quite a few examples. The problem, from a team perspective, is that none of the examples are encapsulated or self-contained enough for re-use. Using an example in a real solution involves to much cut & paste and code change. Obviously, this (anti-) pattern results in poor security implementations, opportunities for hackers, etc.
This implementation, however, is intended to provide a single location for all OAuth and WRAP implementation which can be easily reused by each member of the team. Although a person or subset of a development team needs to understand what’s going on in AMT.IdentityModel.OAuth classes, most developers will just need to use the WRAPHandler class with appropriate token indicators.
For example, to obtain a Simple Web Token (SWT) given a user name and password (AMT OAuth types in blue):
// Instantiate the appropriate WRAP handler based on the types of token in play. These lines show // a WRAP handler which returns a SimpleWebToken (SWT) given a user password claim token WRAPHandler<Microsoft.IdentityModel.OAuth.SimpleWebToken, SWTUserPasswordClaimToken> wrapHandler; // Notice that the Simple Token Service endpoint and application scope are included when instantiating // the WRAP handler. This provides for the ability to retrieve multiple tokens for the same endpoint, etc. wrapHandler = new WRAPHandler<SimpleWebToken, SWTUserPasswordClaimToken>(m_params.STSEndpoint, m_params.Scope); // Create the claim token using the appropriate claim token type (user password in this case) wrapHandler.ClaimToken = new SWTUserPasswordClaimToken(m_params.IdentityName, m_params.IdentityPassword); // Now just retrieve the token from the STS SimpleWebToken swt = wrapHandler.RetrieveTokenFromSTS();
To use a symmetric key claim token, the developer just needs to change the claim token type and construct with the appropriate credentials (relevant changes in red):
// Instantiate the appropriate WRAP handler which takes a symmetric key claim token WRAPHandler<Microsoft.IdentityModel.OAuth.SimpleWebToken, SWTUserSymmetricKeyClaimToken> wrapHandler; wrapHandler = new WRAPHandler<SimpleWebToken, SWTUserSymmetricKeyClaimToken>(m_params.STSEndpoint, m_params.Scope); // Create the claim token using the appropriate claim token type and credentials (symmetric key in this case) wrapHandler.ClaimToken = new SWTUserSymmetricKeyClaimToken(m_params.IdentityName, m_params.IdentitySymmetricKey); // Now just retrieve the token from the STS SimpleWebToken swt = wrapHandler.RetrieveTokenFromSTS();
That's it! The WRAPHandler does all the heavy lifting for you. As you can see from the code above, development team benefits include:
* Compile-time correctness validation - A WRAPHandler declared for symmetric key claim will not compile with user password claim. How much time would this save your development team over debugging?
* Gaurantees appropriate token type usage and return type - Only the token types declared are allowed; retrieving token from STS returns only the declared type. If you've ever hand-crafted code for claims, you know how inter-mixed the tokens can become. Again, saves lots of coding and debugging time.
* Single code path for claims and tokens - How secure is your team's application if claims and token code is copied around? If you find a bug, how many places need to be updated?
* Opportunity for token caching, etc. - Another benefit of single code path is that your application could implement appropriate token caching and other features without changing multiple areas of code.
(NOTE: The code above was copied from the tests included with the source code, but has been edited for readability. Please see the source code for more detailed examples.)