Howdy folks, It's time for a new installment in our Azure AD and Windows 10 series! In earlier posts you have learned how Windows 10 offers deep Azure AD integration, both on enterprise owned and personal devices. Windows 10 makes it possible to sign in your Windows 10 device directly with your work account in Azure AD, or add your work account to your personal Windows 10 device (to which you signed in with your personal Microsoft account). In both cases, this allows you to access Azure AD protected resources seamlessly, enjoying single sign on with all the apps running in your Windows session. How is that achieved? Windows 10 exposes new identity API, which makes it easy for applications to take advantage of the user tokens stored in the system. Microsoft applications use those API, and so can you. I have asked Vittorio, a Principal PM in my team working on developer experience, to walk you through the integration with Azure AD with new API in your Windows Universal Apps.
Keep the feedback and suggestions coming!
Best Regards,
Alex Simons ( @Alex_A_Simons )
Director of Program Management
Microsoft Identity and Security Services Division
------------------------------
Hello everybody!
Windows 10 is unique among all modern operating systems – as of today, it is the only one offering OAuth2 integration directly in its native API. Apps targeting the Universal Windows Platform use a consistent set of API for obtaining security tokens to gain access to protected resources, thanks to a pluggable architecture that can expose any provider through a consistent programming façade. Microsoft's identity providers (Azure AD and MSA) are available out of the box, making it super easy for you to take advantage in your apps of the accounts already present in the system. In this post I am going to give you a quick introduction to the new API architecture, show you some sample code demonstrating how to get an Azure AD token, and discuss the relationship between the new Windows 10 identity API and ADAL, our existing Azure AD family of developer libraries. Ready? Let's dive in!WebAccountManager API
Delegated authorization and sign in via web providers is a fundamental capability for all modern applications – and it is implemented prevalently via OAuth2. To help developers integrating such capabilities in their applications, Windows 8 introduced a new system API – the WebAuthenticationBroker – which provided developers with a canvas to paint the authentication and consent experiences without worrying about rendering web views in their own code, or even managing cookie-based sessions. That made it easier to host web authentication experiences from native apps, but the application developer was still responsible for crafting protocol requests and parsing responses. The approach required a familiarity with protocol mechanics that most app developers do not have. Since then, things have improved significantly. Windows 10 goes much further in supporting the scenario, introducing new API that take care of all protocol details, handle token caching and even integrate with the accounts already present on the system. The new API revolves around a pluggable architecture, which allows identity providers (such as Azure AD, MSA or any other identity provider) to install specialized plugins - called WebAuthenticationProviders - that take over all the authentication and session management concerns for all apps running on the machine. The Universal Windows Platform (UWP) introduces a new primitive, the WebAccountManager, which offers a consistent programming façade on top of all WebAuthenticationProviders installed in the system. In practice, that means that with the same system API you can get tokens from any of the providers know by the system – and if the token corresponds to a user already signed in on the machine, achieve single sign on.
Let's take a look at the API in action by walking through a simple sample.
Using WebAccountManager to Integrate with Azure AD
Most of the times, using the new API boils down to the following pattern:- Select the provider you want to a token from
- Construct the token request and pass it to the provider to get back a token
- Use the token to access the resource you are targeting
string tenant = "developertenant.onmicrosoft.com";
string authority = "https://login.microsoftonline.com/" + tenant;
WebAccountProvider wap =
await WebAuthenticationCoreManager.FindAccountProviderAsync("https://login.microsoft.com", authority);
Given that I want a user from a specific tenant, I specify that tenant as the authority. If I'd want this app to work with any Azure AD tenant, I would pass "organizations" in lieu of the authority parameter. Note . As mentioned, this API abstracts away the differences between providers: this syntax would work just as well if I'd be looking to get a MSA token – in that case, I'd pass "consumers" instead. Once you get a hold on the desired provider, you can construct the token request. Here there's how the code looks like for Azure AD.string clientId = "a9b55b7d-66af-4de9-9ee7-c7b04106bdef";
string resource = "https://graph.windows.net";
WebTokenRequest wtr = new WebTokenRequest(wap, string.Empty, clientId);
wtr.Properties.Add("resource", resource);
The WebTokenRequest constructor takes the absolute minimal sets of parameters required for crafting an OAuth2 request. Being Azure AD a multi tenant system, you are required to provide extra information – such as the resource parameter, indicating what is that you are requesting access to (in this case, the Graph). The WebTokenRequest allows you to specify provider-specific information simply by adding them to a generic property bag. Once you have the request ready, you fire it up with the following code.WebTokenRequestResult wtrr = await WebAuthenticationCoreManager.RequestTokenAsync(wtr);
if (wtrr.ResponseStatus == WebTokenRequestStatus.Success)
{
accessToken = wtrr.ResponseData[0].Token;
var account = wtrr.ResponseData[0].WebAccount;
var properties = wtrr.ResponseData[0].Properties;
}
This is where most of the magic happens. The provider you specified takes over, trying to use the currently signed in user (or any account saved on the system) to obtain the token you requested without prompting the user. If the token can be obtained without interaction, as it will often be the case on cloud domain joined or classic domain joined machines, the call to RequestTokenAsync will return right away. In case interaction is required, either for showing consent or for gathering authentication factors, the API will take care to automatically prompt the user with the correct experience. Once you obtain the requested token, you can invoke the Graph with it - just as you'd do on any traditional app: via raw REST calls or via client library, according to your preferences. Let's see how using such an app would play out on a desktop PC or a tablet cloud-joined to my test directory developertenant.onmicrosoft.com. Here there's the initial UX of a simple directory searcher UWP application.Say that we hooked up the token acquisition logic to the Search button. As I press the button, RequestTokenAsync automatically uses the developertenant.onmicrosoft.com account I am signed in with – but given that this is the first time I run the app, I am asked to grant consent to it:
As soon as I accept, RequestTokenAsync returns the requested token to the app code – which can now use it to query the directory Graph and display the results.
Now, the beauty of UWP apps is that they can run *as is* on phones running Windows 10 – no code changes required. You can see this by yourself by changing the debug target to a device emulator and hitting F5 again.
Here there's the UX for the app, automatically formatted for the phone form factor. Enter your query and tap Search.
In this case, I am using a phone that was already configured to use my admin@developertenant.onmicrosoft.com – thanks to that, I don't need to enter any credentials and I go straight to the consent. If I'd be running this on a "clean" device not associated to any user, the code would work just as well: I'd simply be asked to enter my credentials first.
As soon as I grant consent, the app retrieves the token it needs and performs its query. That was easy! If you want to play with the sample on your own machine, you can find its source on GitHub . If you want to know more about WebAccountManager and Azure AD, check out the recording of this //Build/ session ; if you want to hear more about the general architecture of the WebAccountManager API, check out Karanbir's //Build/ session .
WebAccountManager or ADAL?
Since its very first version, Azure AD has been offering developer libraries - Active Directory Authentication Library, ADAL for short – to achieve scenarios like the one we explored here. When should take advantage of the new WebAccountManager API and when you should you keep using ADAL? Simple.- WebAccountManager is Windows 10's native identity API. If you are targeting Windows 10's Universal Windows Platform, use the WebAccountManager. That will give your apps access to the deep Windows10-Azure AD integration features you've been learning about in the past months on this blog. Furthermore: if your app works with providers other than Azure AD and MSA, and that provider is available as WebAuthenticationProvider, WebAccountManager will make it easy to request tokens consistently through your code.
- If your native apps need to run also on older Windows versions (Windows 7, 8.x and corresponding server SKUs, Windows Phone 8.1) or on the desktop, you can use ADAL .NET. Applications written with ADAL .NET will also run on Windows 10, whether they are in the desktop, store and universal formats. In fact, if you already have Windows store apps leveraging ADAL and you want to port them as is to the UWP platform, ADAL 2.x and ADAL.3 code will work – but it will keep tokens in its own cache, instead of leveraging the Windows10 system accounts. ADAL .NET is also indicated for scenarios in which you need apps to have their own identity, without user involvement, or for use of raw credentials – out of scope for WebAccountManager. If you want to target iOS and Android, in which case you have available both the native route (ADAL iOS, ADAL Android) and the multiplatform route (Xamarin with ADAL .NET 3.x, Cordova with the ADAL Cordova plugin).