Microsoft-authentication-library-for-dotnet: New API is busted for Native Client applications

Created on 24 May 2018  路  20Comments  路  Source: AzureAD/microsoft-authentication-library-for-dotnet

I need an example of this library working with a Native Client and Azure AD B2C. I have an Win8.1 application working just fine with the Microsoft.Identity.Client 1.0.0. When I tried to upgrade to UWP and Microsoft.Identity.Client 1.1.2, the parameters changed. I tried modifying the ClientId to use a new format that I saw on one of the issue pages, but it doesn't work.
So the old API and old format works just fine, new API and new format give me a message: AADB2C90117: The scope 'api://2c2fb9e7-a056-4506-9638-ab5bf9e3ad2c' provided in the request is not supported.
My native client doesn't have a scope, so I'm not sure what, if anything, to use for a scope when formatting. Here's the latest try that's causing this error: api://2c2fb9e7-a056-4506-9638-ab5bf9e3ad2c.

Most helpful comment

Holy sh*t! That worked! Thanks for your help. Your documentation needs work, though. I've wasted three days on this. The example that Jean-Marc referenced had the scope name without the URI information:

string[] scopes = new string[] { "demo.read" };

Makes me wonder if it really works on an Azure AD.

All 20 comments

@Dark-Bond

You can find several examples of Native client applications leveraging MSAL in https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-code-samples#desktop-and-mobile-public-client-apps, and in particular https://github.com/azure-samples/active-directory-dotnet-native-uwp-v2 which is a UWP application calling the Microsoft Graph.

The error you see is telling you that the scope parameter you used to call AcquireTokenAsync is not right. Are you trying to call a Web API which ClientID is 2c2fb9e7-a056-4506-9638-ab5bf9e3ad2c.? In that case you are missing a scope after the guid for the Web API for instance "/access_as_user". This scopes are defined in the application registration portal where the Web API was registered (https://apps.dev.microsoft.com). You might also want to check out the https://github.com/azure-samples/active-directory-dotnet-native-aspnetcore-v2 sample which shows how a native application calls a V2 Web API.

Finally you might want to have a look at the conceptual documentation for MSAL.NET: https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-interactively.

I'm proposing to close this issue (as I don't think that's an issue with the API) but feel free to reopen if you disagree

When I create a Native Client for my AAD B2C Application, I'm not given the option of creating a 'scope' for it. This seems to be a Web API concept and I don't see how it applies to the options I'm given when I configure my application.

@Dark-Bond : the scope is not for your Native application, but for the Web API that this native application calls. Can you please explain your scenario a bit (what does your Native app do), so that we can help you better.
BTW, if it calls an Azure AD V1 web API, you might want to read https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Adal-to-Msal#scopes-for-a-v1-application.

Yes, that's the problem. You are giving me an example of a format string for the client (e.g. "api://{clientId}/{scope}". The old API didn't require any concept of a 'Scope' for getting a security token and the B2C Applications don't give you the option for setting up a scope. So how is a Native Client (e.g. Win8, WPF, UWP) supposed to use this API to get a token? (No, I'm not using a V1 application)

The example you cited above for a UWP uses the same ClientID format that I used in the 1.0.0 version (and that still works with the old API).

private static string ClientId = "0b8b0665-bc13-4fdc-bd72-e0227b9fc011";

This now returns a Argument Exception in the 1.1.2 version.

@Dark-Bond : do you have a repro project that we could look at?

Adding @parakhj for the B2C question. The AAD V2 endpoint requires a scope, but I don't know for B2C. Do you want to try with "api://{clientId}/.default" ?

I don't have a small enough repo to post. Possibly this weekend I can create a basic web service that just logs in. There are no scopes in the B2C setup for a Native Client. I don't know how I would begin to guess at a default scope (even if one exists). I just know that the old API (1.0.0) didn't require a scope to find the authority and log in.

@Dark-Bond, I don't thik you should create a repro during the WE. I'll try to have a look at the differences between 1.00 and 1.0.2 from this point of view. We'll wait for Parakh's answer for B2C, but if you can just try if ".default" works, this would be good

@Dark-Bond Check out this article to see how to configure scopes in B2C applications: https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-access-tokens

No, nothing works. I took the example from "https://github.com/Azure-Samples/active-directory-dotnet-native-uwp-v2" and added these lines:

    //Below is the clientId of your app registration. 
    //You have to replace the below with the Application Id for your app registration
    private static string ClientId = "2c2fb9e7-a056-4506-9638-ab5bf9e3ad2c";
    private const string Authority = "https://login.microsoftonline.com/tfp/darkbonddevelopment.onmicrosoft.com/B2C_1_Sign_In/oauth2/v2.0/authorize";
    public static PublicClientApplication PublicClientApp { get; } = new PublicClientApplication(ClientId, Authority);

And in the main application, I set:

    //Set the scope for API call to user.read
    string[] scopes = new string[] { ".default" };

And I got:

Microsoft.Identity.Client.MsalServiceException: 'AADB2C90117: The scope '.default' provided in the request is not supported. Correlation ID: a2f6f28f-e89f-43d4-bd90-3a7246b2debd Timestamp: 2018-06-01 00:47:46Z'

I've tried several other combinations including making a dummy Web API for the application with a dummy scope. Nothing works. I zipped up the example (really, I just changed three lines). Feel free to use my B2C tenant for authentication (or your own, whatevs). If you manage to get a login screen to come up, the user name is '[email protected]' and the password is 'H0l0gr4m'.

active-directory-dotnet-native-uwp-v2.zip

@parakhj - I also followed the instructions on the page you gave, to the letter. The results were no different: "The scope provided in the request is not supported."

The scope you are using should look something like:

https://fabrikamb2c.onmicrosoft.com/demoapi/demo.read

so the format is:

https://{tenantName}/{AppID URI}/{Scope value}

Holy sh*t! That worked! Thanks for your help. Your documentation needs work, though. I've wasted three days on this. The example that Jean-Marc referenced had the scope name without the URI information:

string[] scopes = new string[] { "demo.read" };

Makes me wonder if it really works on an Azure AD.

Glad to know! Sorry that it took you so long. Which documentation are you referring to?

https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-access-tokens
Now that I know what I'm looking for, I can pull apart one of the URIs that you have as an example, but not in a million years would I have associated the garbage at the end of that address with the 'scopes[]' variable in the example that Jean-Marc provided.

@Dark-Bond, indeed most of our examples are for the MSFT Graph, which has well known scopes like User.Read, and therefore for these you don't need to provide the URI to the resource

I appreciate that, but for those of us working with the Native Applications, the lack of documentation can be a real time-killer.

@Dark-Bond : thanks for the feedback
are you familiar with MSAL.NET conceptual documentation?
What else would you want to see there?
Do I understand that you'd like more documentation about how to get tokens for Azure AD B2C ?

The MSAL.NET documentation isn't all that useful. I've got a fair idea of the concepts, it's the actual implementation that causes us consumers of these libraries the pain. I understand that the packages are coming out in rapid-fire order and it's tough to go back and make sure the examples keep up with the new libraries. In this instance, we're dealing with voodoo. You have an example that works with Azure AD using plain 'scope' names, but for some reason the B2C API needs complete URIs for scopes. I've never seen an actual example of a URI for a scope and never would have made the connection without bothering you all here on Github.

However, in the grand scheme of things, I'm glad you were here and responsive. The worst possible scenario would have been to try to build this stuff without being able to consult with someone with inside information.

Was this page helpful?
0 / 5 - 0 ratings