Microsoft-authentication-library-for-dotnet: AD B2C - tenant.b2clogin.com is not providing same abilities as login.microsoftonline.com for existing AD B2C code

Created on 20 Apr 2020  ·  15Comments  ·  Source: AzureAD/microsoft-authentication-library-for-dotnet

Which Version of MSAL are you using ?
MSAL 4.11? Believe it matches the version of Microsoft.Identity.Client? (which is 4.11)

Platform
dotnetcore

What authentication flow has the issue?
Azure Functions - not on behalf of users

Is this a new or existing app?
Existing code that has been working with login.microsoftonline.com, but not with tenant.b2clogin.com

Repro

Expected behavior

As an example of the problem and expected behavior, an azure function is being used to get a token and then a list of users from ADB2C with a client secret using .WithAuthority and specificying login.microsoftonline.com

With the deprecation of login.microsoftonline.com for AD B2C it would be expected to be able to switch to using tenant.b2clogin.com and get the same type of ability.

Actual behavior

Not matter what options are chosen an error similar to: "Microsoft.Identity.Client: AADSTS50049: Unknown or invalid instance." is thrown. .WithAuthority has been tried, .WithB2CAuthority as well.

There is a lot of logic going on that we already have in place with Azure Functions tieing together many apis and AD B2C. Without the ability to act without user context a significant amount of benefits for using AD B2C goes away.

Possible Solution
If there is current no possible way to interact with ADB2C without user context then this needs to please be fixed as soon as possible. This is critically needed.

Guidance would be extremely appreciated if this is not a bug and there are other ways of doing so.

answered question

Most helpful comment

There is a lot of confusion here. Let me try break this down.

ADAL - Uses AAD /authorize and /token endpoints
MSAL - Ability to use AAD /authorize and /token endpoints. And ability to use B2C /authorize and /token endpoints.

AAD tenant - contains only AAD endpoints. It is a single token issuer
B2C tenant - contains AAD and B2C token endpoints. There are two token issuers

A B2C tenant contains:

  • AAD endpoint: login.microsoftonline.com THIS IS NOT BEING DEPRECATED
  • AAD B2C endpoint: login.microsoftonline.com + B2C policyId parameter (this is being deprecated). And tenantName.b2clogin.com+ B2C policyId parameter
    Based on the authentication request, the request is routed to the two different token issuers.

The next key point:

  • AAD endpoints allow you to obtain tokens to your applications protected by an AAD Application Registration.
  • AAD endpoints allow you to obtain tokens to Microsoft APIs, since they are also protected by AAD on our side. Such as MS Graph API.
  • AAD endpoints allow client_credentials
  • B2C endpoints allow you to obtain tokens to your applications only protected by an AAD B2C Application Registration.
  • B2C endpoints do not allow client_credentials

Now, when you use MSAL, you cannot use tenantName.b2clogin.com to obtain a token for MS Graph API, based on the above rule set.
This means a users B2C authentication cannot be used to authorize to AAD protected apps, or Microsoft APIs.

ADAL targeted the AAD endpoints, so this is why it worked, you essentially did an AAD authentication against a B2C tenant.

When you use login.microsoftonline.com and don't provide any policy id parameters against a B2C tenant, you hit the AAD endpoints of the B2C tenant, again it works. You can get tokens to Microsoft Graph API for example, using the users context. This should work with MSAL, just configure it as you would for any other AAD tenant, instead use your B2C tenant name.

When you use tenantName.b2clogin.com and provide any policy id parameters against a B2C tenant, you hit the AAD B2C endpoints of the B2C tenant, now it will not work as you expected it to. Hopefully the above clarifies why. And since there is no deprecation of the AAD endpoint, you don't need to be using this domain name for this type of call.

All 15 comments

@bgavrilMS @vigunase @ktsakas @jennyf19 Thanks - opened the new ticket

@drewid for B2C applications, you should not use .WithAuthority, but .WithB2CAuthority. Here the fact that you get an AADSTS error and not an AADB2C error indicates that you've been using .WithAuthority

Also, when you write Azure function not behalf of the user, do you mean that you've been trying to user AcquireTokenForApp ?
If that's the case, please know that Client credentials (the underlying protocol for AcquireTokenForApp), is not supported by B2C.

Yes I understand it is now supposed to be WithB2CAuthority.

Can you please provide additional clarity?

1) for B2C why does it work for with login.microsoftonline.com then?
2) why does it work with ADAL.
3) how the are non-user interactions ever supposed to work with B2C? I have many, many use cases and business logic that cannot use user interactions.
4) what method to do so?

This is extremely frustrating. How can MS deprecate working capabilities of ADAL and MSOL and not provide equivalent or better features?

This is completely killing plans to use MS wholeheartedly for Azure.

@drewid - ADAL never worked with B2C authorities. You must have been targeting AAD (i.e. the B2B token provider). "login.microsoftonline.com" continues to be the AAD endpoint.

I think what you are actually doing is to use ADAL to get a token for an application (not for a user), from the Graph, and use a graph API to list the users you are interested in? To do this with MSAL, please see https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-credential-flows

MSAL fully supports of all ADAL's features.

@drewid ; I understand your frustration, but I think that we have some mis-understanding, here. Let's try to understand what happens. With my knowledge, client credentials have never worked with B2C (as Bogdan indicates)

  1. Which authority were you using with login.microsoftonline.com ? I don't think that this was a B2C authority, we'd want to check that
  2. what was your ADAL code.

If you don't want to share things publically, feel free to email me directly (Jean-Marc.Prieur at microsoft.com)

Client credentials fully work for interacting with B2C when using ADAL, you can manage accounts by username or email etc. I have working code that does that and the MS B2CGraphClient sample project shows that. With that project you can do the following for B2C users:

  • GET-USER
  • CREATE-USER
  • UPDATE-USER
  • DELETE-USER
  • GET-EXTENSION-ATTRIBUTE
  • GET-B2C-APPLICATION

It would be really disappointing if I have to use ADAL, which is not recommended, to be able to interact with B2C without user-context. Given all the trumpeting that has been done about how flexible B2C is and being able to interact with other systems I would be shocked if a system-level interaction is not available - it makes zero sense.

My big questions are:

  • If MSAL can't do it without user-context, why is that artificial limit in place?
  • Why can I get B2C users using the MSAL example code for login.microsoftonline.com but not when using tenant.b2clogin.com
  • If I have to use ADAL how long will it be supported?

Thanks for helping

Is this sample the one that you are trying out? https://github.com/AzureADQuickStarts/B2C-GraphAPI-DotNet/tree/master/B2CGraphClient

The sample is not getting a token from B2C, but from AAD (B2B). The token is valid for Graph, and you can use it to query the graph endpoint with the methods you exposed. If you follow the wiki link I posted earlier, you will find a sample on how to do the same using MSAL.

@aiwangmicrosoft - that sample is using ADAL v2. Could you please liaise with the B2C team to get the sample removed / reworked for MSAL?

I think even the offical docs show updated code / MSAL on how to do this - https://docs.microsoft.com/en-us/azure/active-directory-b2c/manage-user-accounts-graph-api#code-discussion

There is a lot of confusion here. Let me try break this down.

ADAL - Uses AAD /authorize and /token endpoints
MSAL - Ability to use AAD /authorize and /token endpoints. And ability to use B2C /authorize and /token endpoints.

AAD tenant - contains only AAD endpoints. It is a single token issuer
B2C tenant - contains AAD and B2C token endpoints. There are two token issuers

A B2C tenant contains:

  • AAD endpoint: login.microsoftonline.com THIS IS NOT BEING DEPRECATED
  • AAD B2C endpoint: login.microsoftonline.com + B2C policyId parameter (this is being deprecated). And tenantName.b2clogin.com+ B2C policyId parameter
    Based on the authentication request, the request is routed to the two different token issuers.

The next key point:

  • AAD endpoints allow you to obtain tokens to your applications protected by an AAD Application Registration.
  • AAD endpoints allow you to obtain tokens to Microsoft APIs, since they are also protected by AAD on our side. Such as MS Graph API.
  • AAD endpoints allow client_credentials
  • B2C endpoints allow you to obtain tokens to your applications only protected by an AAD B2C Application Registration.
  • B2C endpoints do not allow client_credentials

Now, when you use MSAL, you cannot use tenantName.b2clogin.com to obtain a token for MS Graph API, based on the above rule set.
This means a users B2C authentication cannot be used to authorize to AAD protected apps, or Microsoft APIs.

ADAL targeted the AAD endpoints, so this is why it worked, you essentially did an AAD authentication against a B2C tenant.

When you use login.microsoftonline.com and don't provide any policy id parameters against a B2C tenant, you hit the AAD endpoints of the B2C tenant, again it works. You can get tokens to Microsoft Graph API for example, using the users context. This should work with MSAL, just configure it as you would for any other AAD tenant, instead use your B2C tenant name.

When you use tenantName.b2clogin.com and provide any policy id parameters against a B2C tenant, you hit the AAD B2C endpoints of the B2C tenant, now it will not work as you expected it to. Hopefully the above clarifies why. And since there is no deprecation of the AAD endpoint, you don't need to be using this domain name for this type of call.

@JasSuri - many, many thanks for a great overview.

Are the following statement correct then?

  • The "tenant.b2clogin.com" format is really for only B2C end-user facing interactions.
  • The "login.microsoftonline.com" format can still be used for any behind the scenes, non-user-interaction work on managing users and attributes, even if they are specific to B2C

The "tenant.b2clogin.com" format is really for only B2C end-user facing interactions.

Correct.

The "login.microsoftonline.com" can still be used for any behind the scenes, non-user-interaction work on managing users and attributes, even if they are specific to B2C

Also correct, and it’s the only way. B2C attributes are inside the AAD component of a B2C tenant, the directory attribute manipulation works via MS Graph API just like it does for a AAD tenant.

Many thanks! Much better clarity. @JasSuri it deserves its own article. :)

@mmacy Can we capture what @JasSuri wrote above in either the docs or in the wiki? thx.

@jennyf19 Yes, we definitely need a doc that lays out the endpoints. This is gold - nice work, @JasSuri. This will have to go to May sprint, earliest, but I'll get something stubbed out.

Awesome...thanks for the quick response @mmacy ...and yes @JasSuri is golden!
Thanks @drewid for bringing this to our attention.

Was this page helpful?
0 / 5 - 0 ratings