Tuesday, January 14, 2014

Azure Active Directory, Xamarin and OAuth2

This is one of those posts where I’m brain dumping my findings.
In a nutshell, I wanted to write a Xamarin App which authenticates against a Windows Azure Active Directory (WAAD) and then access a Web Api which is secured using WAAD.
There are quite a lot of tutorials out there but most use ADAL (Active Directory Authentication Library) to handle the OAuth2 which isn’t a Portable Class Library. I grabbed the Xamarin.Auth library which abstracts the OAuth2 protocol framework away from me a bit.
So I followed the instructions here (http://www.cloudidentity.com/blog/2013/07/23/securing-a-web-api-with-windows-azure-ad-and-katana/), plumbed in the values to the OAuth2Authenticator class,
image 





and… Nothing.. Failure..


So, here’s what I’ve learnt about OAuth2 in Azure Active Directory (as of 10/Jan/2014).


When we are a Native Client with no client secret, Azure AD does not use OAuth2’s implicit flow where we get a token immediately. It uses the code grant flow where after authenticating we are given a code which we swap for a token.


When we initially get the code we need to pass another querystring parameter called “resource” which identifies the Application in Azure Active Directory that we want to call. This resource is the App Id Uri on Azure’s portal. And from what I can see, we don’t need to pass a scope.


image


And when we’ve finally got the token it needs to go as a Bearer token in the headers of subsequent requests. This is written in the spec, but for whatever reasons the Xamarin.Auth component seems to put it on the querystring.


So the main difference from most of the OAuth2 implementations seems to be getting that initial code. The Uri you need is:


https://login.windows.net/<tenant>/oauth2/authorize?client_id=<client>&resource=<app_id_uri_from_waad>&redirect_uri=<redirect_uri_from_waad>&state=<random>&response_type=code

7 comments:

Ben Reierson said...

Hi Graeme,
Just wondering if you actually got the Xamarain.Auth component to work, or if this is where you're stuck?

I have been banging my head against the same thing and haven't figured out how to make it work.

logesh R said...
This comment has been removed by the author.
logesh R said...

Hi,

I am stuck up with the same thing. I you have solved this please let me know. It would be of great help..

Ben Reierson said...

@logesh
I did manage to solve this by modifying the Xamarin.auth source code a bit to work with Azure AD.

The changes were pretty minor:
1. Added a new constructor to Oauth2Authenticator that takes a resource argument but not a clientsecret. Native apps talking to Azure AD don't need a client secret, but they are supposed to pass a resource they plan to access.

OAuth2Authenticator(string clientId, string resource, Uri authorizeUrl, Uri redirectUrl, Uri accessTokenUrl, GetUsernameAsyncFunc getUsernameAsync = null)

2. Change the RequestAccessTokenAsync method to pass the resource object when not null.

3. I also changed OAuth2Request to properly pass the token as a bearer header, instead of as an argument in the url. Not sure if this was strictly necessary.

I wasn't sure if these changes would break compatibility with other services, so I didn't directly submit them to the github project but filed an issue instead.
Hope that helps.

logesh R said...

Hi Ben,

Thanks a lot... I am relatively new to GitHub.. Can I take a version of the changes that you did the Xamrain.Auth and refer that dll? Any pointers to it would be greatly helpful to me...

Ben Reierson said...

Honestly, I don't know that using xamarin.auth is the best way to go now that Microsoft released updated xamarin bindings for their native ADAL implementation.
https://github.com/AzureADSamples/NativeClient-Xamarin-iOS
https://github.com/AzureADSamples/NativeClient-Xamarin-Android

Maybe give those a shot first.

DevRabbit IT Solutions Inc. said...

Hey Graeme,

Interesting article, resonated with me from start to finish on "Azure Active Directory, Xamarin and OAuth2". Helpful for Xamarin Developers

Thank you for the giveaway!