Controlling the login flow when using ADAL for WAML

In this post, I will show you a few tricks that enable you to make best use of ADAL for using Oauth2 Tokens instead of Management Certificates.

Caption: The login screen on my screen.

Caption: The window when pressing using another account.

I have been working on our Azure Management client that we use to maintain our Azure stuff at Composite. We are preparing to release things to the public and while we was testing the experience on different machines and setups, we found some issues related to how ADAL (Active Directory Authentication Library).  A good place to find more information about working with Windows Azure Active Directory and ADAL is at www.cloudidentity.net where Vittorio Bertocci blogging a lot by these things. And if you are looking for posts about using WAML, remember to check out www.bradygaster.com/ where Brady Gaster  have some nice tutorials on using that.

The problem we was facing when the user needed to authorize himself against either the common endpoint or a given active directory, was that the login forced him to login with an organizational account in some cases. Things seemed to be different for different people at their machines, like there was some state from somewhere else doing something. 

var ac = new AuthenticationContext("https://login.windows.net/" + ActiveDirectoryTenantId);
AuthenticationInfo = ac.AcquireToken(
                         resource: "https://management.core.windows.net/",
                         clientId: "1950a258-227b-4e31-a9cf-717495945fc2",
                         redirectUri: new Uri("urn:ietf:wg:oauth:2.0:oob"));

Above you see what our original code looked like for logging in, here the clientId/redirectUri is from the Windows Azure Powershell Tools. The first thing I added was the option to clear any cookies that could influence the login.

private void ClearCookies()
{
    NativeMethods.InternetSetOption(IntPtr.Zero, NativeMethods.INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0);
}

private static class NativeMethods
{
    internal const int INTERNET_OPTION_END_BROWSER_SESSION = 42;

    [DllImport("wininet.dll", SetLastError = true)]
    internal static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer,
        int lpdwBufferLength);
}

I also changed a few places such a prompt was forced even though the tokens could come from the cache. You can do this by passing PromptBehavior.Always to the AcquireToken. And if you pass in the following as the extraQueryParameters to the AcquireToken, you get the nice login screen shown in the image at the top where it will direct you to the correct login page based on your email, or let you select if you have the same email used for a liveid and a organizational account.

"site_id=501358&display=popup"

ADAL Token Cache

Just another great information that you should not miss. Using ADAL with WAML or not, you can cache the tokens from session to session, not forcing the user to login every time he closes your application. As default, you will get an in Memory Cache and therefore when the applications closes he will have to reauthorize himself. Instead of this in memory cache I am using the implemented cache found here: http://code.msdn.microsoft.com/AAL-Native-Application-to-fd648dcf/sourcecode?fileId=96196&pathId=1866494180

It stores the tokens in the Credential Manager of windows.

Hope that is helpful. 



comments powered by Disqus