OAuth2 and OpenID Connect – Part 3

Accessing a Protected Resource

In this third and final article we’ll have a look at how to access a protected resource using an access token. In part 1 and part 2 we looked at how to authenticate and obtain an access token from an OAuth2/OpenID Connect identity server.
We will now look at how to include that token as part of a request for a protected resource and how the protected resource can check the token. The example projects can be found here:
https://github.com/maz100/OAuth2.Demo/tree/master/MyReallyUsefulWebApi
In the test project there is a test called TestGet_valid_token_is_used_to_call_my_really_useful_api. This test obtains an access token using the resource owner password credential flow. This flow differs from the implicit flow used in previous articles in that it passes the resource owner’s username and password to the identity server. It’s a flow which should be used with some caution in real world scenarios as it exposes highly privileged credentials to the client. However it would not be practical to have a unit test which displayed the identity server login page. The code uses the Thinktecture.IdentityModel.Client nuget package which encapsulates the OAuth2 flows making it very easy to request the token. To make the request for the protected resource we use a regular HttpClient instance but the Thinktecture client library attaches an extension method called SetBearerToken. This sets the token in the authorization header using the bearer scheme which is the preferred way to transmit the access token in the request (as defined in RFC 6750). We then set the URI for the request and await the async response.

On the api side we’re plugging in the token validation as part of the OWIN pipeline. The Startup class uses some IAppBuilder extension methods defined in Thinktecture.IdentityServer.v3.AccessTokenValidation and Thinktecture.IdentityModel.Owin.ScopeValidation. Essentially this plugs in the logic to look at the incoming token via the token validation endpoint which we used in the .net 2.0 project to decrypt the token so that we could display it on screen (not something we’d want to do in a real application). The claims are then extracted from the decrypted token and passed to a ClaimsIdentity instance which is then passed as a constructor argument to an AuthenticationTicket instance which is in turn passed as an argument to a call to SetTicket on the AuthenticationTokenReceiveContext.

What this all means is that the user can now be authorized to use the api according to their claims. In this example we’ve specified that users must have read and write access to be considered authorized. We then just decorate our api methods with an AuthorizeAttribute and they will only be able to access the method if they have the read and write scopes defined in the access token. For more fine-grained control have a look at the ResourceActionAuthorizeAttribute and the ScopeAuthorizeAttribute in the Thinktecture.IdentityModel source.

Assuming you have both the identity server and MyReallyUsefulApi running both tests should pass indicating that access is granted when a valid token is received and that it is denied when that token is not present.

To summarise, in this final article on OAuth2 and OpenID Connect we’ve seen how to include an access token with a request to a protected resource and how to make that resource validate the token and allow access according to the claims within it. I’d recommend becoming familiar with the specs for both OAuth2 and OpenID Connect. Security is a complex domain and ultimately responsibility lies with you for your own applications. I’ve made extensive use of the open source Thinktecture repositories because they are very comprehensive and active projects. This series of articles has documented how I’ve used code from these projects and transplanted it into my own very simple projects. Doing this was very useful for my own understanding of OAuth2 and OpenID Connect. I don’t profess to be an expert in these areas so please don’t consider this to be anything like an out of the box solution. However I do hope that I’ve provided enough information to help others to get started.

Advertisements

About maz100

I'm interested in the music called jazz, photography, my wife and two daughters, food, wine, software design and furniture...to name but a few.
This entry was posted in Security and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s