How to AcquireToken with PromptBehavior in the latest Microsoft.IdentityModel.Clients.ActiveDirectory

kumar picture kumar · Jun 24, 2016 · Viewed 10.7k times · Source

In the older versions of Microsoft.IdentityModel.Clients.ActiveDirectory there is AcquireToken with PromptBehavior parameter

var context = new AuthenticationContext("https://login.windows.net/tenantId");
var result = context.AcquireToken(clientId: clientIdValue, redirectUri: new Uri("http://localhost/Appcycle"), resource: "https://management.core.windows.net/", promptBehavior: PromptBehavior.Auto);

In Microsoft.IdentityModel.Clients.ActiveDirectory v3.10 there is only AcquireTokenAsync

var authParam = new PlatformParameters(PromptBehavior.Auto,false);
var result = context.AcquireTokenAsync("https://management.core.windows.net/", clientid, new Uri("http://localhost/AppPoolRecycle"), authParam);
result.Wait();

When I run this I get error {"Invalid owner window type. Expected types are IWin32Window or IntPtr (for window handle)."}

Not sure if this is due to I am running on a console application. If so how do i get it to work?

Answer

Saca picture Saca · Jun 26, 2016

The reason you're getting this error is because you are passing in "false" for the second parameter in the PlatformParameters constructor.

In the latest version of ADAL (Microsoft.IdentityModel.Clients.ActiveDirectory v3.10), this second parameter is (from https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/blob/7c9091a0edecf401fea402275e4a64aca95e40fe/src/ADAL.PCL.Desktop/PlatformParameters.cs):

    /// <summary>
    /// Gets the owner of the browser dialog which pops up for receiving user credentials. It can be null.
    /// </summary>
    public object OwnerWindow { get; private set; }

You're passing in false, which is accepted at compile time given that it's an object, but not at runtime given that it's not a window.

To fix this simply do not pass in this parameter or pass it in as null. This will make your console application launch a window which prompts the user to log in.

If this is meant to be a console application that's supposed to run without any user interaction though, then you should either use the app-only flow via this other overload of AcquireTokenAsync:

    /// <summary>
    /// Acquires security token from the authority.
    /// </summary>
    /// <param name="resource">Identifier of the target resource that is the recipient of the requested token.</param>
    /// <param name="clientCredential">The client credential to use for token acquisition.</param>
    /// <returns>It contains Access Token and the Access Token's expiration time. Refresh Token property will be null for this overload.</returns>        
    public async Task<AuthenticationResult> AcquireTokenAsync(string resource, ClientCredential clientCredential)