Azure OAuth 2.0 – Authorization Code Grant Walkthough

What do I need?

  • You need a resource to secure. I’m using a Web API hosted on OWIN.
  • You’ll need a client which will attempt to access the resource. I’m using a WPF app for no particular reason.
  • The heavy lifting is all done by the Active Directory Authentication Library (ADAL).
  • You need an authorization server, in this case I’ll WAAD which exposes OAuth2 endpoints (amongst others) and is free with the three month trial

Configuring trust in WAAD

If you don’t have a tenant or account in Azure, you can organise a free trial here. Once that is sorted can create an active directory instance through the management portal.

Register your API

  1. Go to your active directory instance in the Azure management portal and click on the Applications menu item
  2. At the bottom of the screen click on the Add button
  3. In the dialog select a name for your application. This how your application will be referred to in the management portal
    rs1
  4. In the next screen set the App Url to https://locahost (because this example will host the API locally) and set the App URI ID to whatever valid URI you’d like to use e.g. http://testresourceserver. It doesn’t need to be network addressable.
    rs2
  5. You can then select any option but for safety sake, select single sign-on
    rs3

Now register your client

  1. Add an application but this time select Native Client Application in the dialog
    tc1
  2. Select a redirect URL. It needs to be a valid URI but doesn’t need to be network addressable for this demo.
    tc2

Configure access to resource

  1. In the management portal go the resource server you just configured and click on the Configure menu item
  2. At bottom, in the client access section, select the client app you just created
    t1

The hard work is done, now for the resource server and client.

Create a resource server

In my example I imported the Microsoft.Owin.Security.WindowsAzure and Microsoft.AspNet.WebApi.OwinSelfHost into a console app. The rest of the project is completely contained in three classes.

Startup.cs – this class configures the server

If you pass through the App ID and tenant, the authentication libraries will take care of the rest.

appBuilder.UseWindowsAzureBearerToken(new WindowsAzureJwtBearerAuthenticationOptions()
{
    Audience = "http://testresourceserver", // APP ID Uri from Azure AD configuration
    Tenant = "yourtenantname" // replace with your tenant, generally <something>.onmicrosoft.com
});

I also need to override the default OWIN authentication and specify OAuth. It’s important to note that although there is an authentication aspect to OAuth2, it’s an authorization framework not an authentication framework.

var authenticationType = new OAuthAuthorizationServerOptions().AuthenticationType;
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(authenticationType));

RolesController.cs – this is the API which the client wants access to.

It simply returns a list of the current principal’s claims and has been decorated with the Authorize attribute

[Authorize]
public IEnumerable<string> Get()
{
    return ClaimsPrincipal.Current.Claims.Select(c => string.Format("{0}: {1}", c.Type, c.Value));
}

Create a client app

The client in this example simply calls into the above Web API and displays the result. To do that it needs to authenticate which, using the azure authentication library, is a two line exercise.

Firstly, an instance of AuthenticationContext is created. You will need to replace “yourtenant” with the name of your AD tenant but the rest of the URL will remain the same.

var authenticationContext = new AuthenticationContext("https://login.windows.net/yourtenantname"); // replace yourtenantname, generally <something>.onmicrosoft.com

The next line will start the process of acquiring an authorization token.

var authResult = authenticationContext.AcquireToken(
    "http://testresourceserver",    // The App ID you set when registering the resource server in WAAD
    "2E217AC6-49EB-4449-90DC-7A476F016BFA", // You client ID assigned by WAAD
    "http://redirecturi");   // more about this later

The authResult will contain an access token and optionally a refresh token. You will need to include the access token as the ‘Bearer’ authentication header.

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
var response = await httpClient.GetAsync("http://localhost:9000/api/roles");

That’s it.

When you run the solution and execute the AquireToken method you’ll see the web authentication broker popup and ask you for credentials.

auth1

Presuming you enter the correct credentials for user in your Azure Active Directory, you will receive an access token to call the API.

Troubleshooting

If you’re uncertain of which parameters to plug into the AquireToken method, they can be found on the management portal I n the quickstart menus of the applications you configured. If the quickstart page doesn’t automatically open when you click on your applications, click on the small cloud with a lightning bolt through it in the top left corner of the page.

ts1

You can find the complete source code here: https://github.com/AdamKorczynski/OAuth2

NOTE: This code sample only works for a thick-client application like the WPF example or a Windows 8 application. The broken must be launched from an app running as a single threaded apartment. If your client is a hosted service such as a Web API, you need to do a bit more work which I’ll get around to demonstrating… soon. If you want to investigate for yourself look into the AuthenticationContext.AquireTokenByAuthorizationCode method. Vittorio Bertocci provides some details in his most excellent blog here: http://www.cloudidentity.com/blog/2013/10/29/using-adals-acquiretokenby-authorizationcode-to-call-a-web-api-from-a-web-app/

Advertisements

One thought on “Azure OAuth 2.0 – Authorization Code Grant Walkthough

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