Aspnetcore: AzureAdB2C configuration defaults to Implicit Flow, when it should default to Auth Code Flow.

Created on 19 Mar 2020  路  18Comments  路  Source: dotnet/aspnetcore

Describe the bug

AzureAdB2C configuration defaults to Implicit Flow, when it should default to Auth Code Flow.

To Reproduce

Create new Dotnet Core 3.1.200 Web App (Model-View-Controller) project.

Ensure provided startup configuration is applied:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(AzureADB2CDefaults.AuthenticationScheme)
                .AddAzureADB2C(options => Configuration.Bind("AzureAdB2C", options));
            services.AddControllersWithViews();
            services.AddRazorPages();
        }

and apply configuration similar to this, referencing an Azure AD B2C tennant with Implicit Flow disabled:

  "AzureAdB2C": {
    "Instance": "https://<tennant>.b2clogin.com/",
    "ClientId": "123-456-6778",
    "ClientSecret": "<secret>",
    "CallbackPath": "/signin-oidc",
    "Domain": "<tennant>.onmicrosoft.com",
    "SignUpSignInPolicyId": "B2C_1_signupsignin1",
    "ResetPasswordPolicyId": "",
    "EditProfilePolicyId": ""
  },

Run application, and attempted sign in will, instead of presenting login page, redirect to the app with the following error displayed in console:

Message contains error: 'unauthorized_client', error_description: 'AADB2C90057: The provided application is not configured to allow the OAuth Implicit flow.

This is due to the Dotnet libraries generating the incorrect response_type=token rather than response_type=code request parameter to the auth endpoint:

https://<tennant>.b2clogin.com/<tennant>.onmicrosoft.com/b2c_1_signupsignin1/oauth2/v2.0/authorize?client_id=123-456-66788&redirect_uri=https%3A%2F%2Flocalhost%3A5001%2Fsignin-oidc&response_type=id_token&scope=openid%20profile&response_mode=form_post&nonce=...&state=...&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0

Further technical details

  • ASP.NET Core version 3.1.200

.NET Core SDK (reflecting any global.json):
Version: 3.1.200
Commit: c5123d973b

Runtime Environment:
OS Name: Mac OS X
OS Version: 10.15
OS Platform: Darwin
RID: osx.10.15-x64
Base Path: /usr/local/share/dotnet/sdk/3.1.200/

Host (useful for support):
Version: 3.1.2
Commit: 916b5cba26

.NET Core SDKs installed:
3.1.200 [/usr/local/share/dotnet/sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.App 3.1.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 3.1.2 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

area-security investigate

All 18 comments

How/why was implicit flow disabled?

Here's how to switch to code flow:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/azure-ad-b2c?view=aspnetcore-3.1#configure-the-underlying-openidconnectoptionsjwtbearercookie-options
https://github.com/dotnet/aspnetcore/blob/7def10277abbb3086c4ee00e369faf6aa27d676a/src/Security/Authentication/OpenIdConnect/src/OpenIdConnectOptions.cs#L220

services.Configure<OpenIdConnectOptions>(
    AzureADB2CDefaults.OpenIdScheme, options => 
    {
        options.ResponseType = OpenIdConnectResponseType.Code;
    });

The default flow is a matter of opinion. As part of the work to move to the v2 endpoints it may well change, but this is in the hands of AAD not us. Implicit flow is enabled by default, and is a reasonable default for us.

So, specifying

            services.Configure<OpenIdConnectOptions>(
                AzureADB2CDefaults.OpenIdScheme, options => 
                {
                    options.ResponseType = OpenIdConnectResponseType.Code;
                });

leads to the following error:

Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: IDX21336: Both 'id_token' and 'access_token' should be present in OpenIdConnectProtocolValidationContext.ProtocolMessage received from Token Endpoint. Cannot process the message.

Also, the IETF recommends not using implicit flow, thus our preferred configuration. https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-04

I鈥檓 confused (happens regularly....) This is also where I thought the components default to Auth Code Flow being a web app, and thus confidential.

https://github.com/dotnet/aspnetcore/issues/18874

Until that recommendation is out of draft we won't look at moving anyway.

As mentioned earlier, I'm confused. How does defaulting to implicit flow relate to this issue where @Tratcher suggests auth code flow - https://github.com/dotnet/aspnetcore/issues/18874#issuecomment-583857909

Is this related to a different Core component, and thank you both for your quick responses

@paulspencerwilliams I was talking about the OAuth providers, not OpenIdConnect.

This issue is a duplicate with https://github.com/dotnet/aspnetcore/issues/18932 were we're considering how to change the default to Code.

Closing as duplicate

I am trying to get my app working with AzureADB2C using Auth Code flow but I get the same error as Paul: Microsoft.IdentityModel.Protocols.OpenIdConnect.OpenIdConnectProtocolException: IDX21336: Both 'id_token' and 'access_token' should be present in OpenIdConnectProtocolValidationContext.ProtocolMessage received from Token Endpoint. Cannot process the message.

Please could this issue be re-opened? Or is it going to be addressed as part of #18932 ?

That error message is very strange. I'm going to re-open this until we at least understand it.

Huzzah I figured out what it was. I wasn't providing a client ID in the scopes parameter so an access token wasn't being returned hence the message. Had tested this with Keycloak as well but I think keycloak adds the client Id to the scope by default.

Good to know, thanks.

@blowdart, implicit flow is no longer by default enabled in the new App registrations (preview) in Azure AD B2C. I just came across this, that the code generated from the templates no longer works with Azure AD B2C using the preview app registrations, without changing the authentication configuration to implicit grant.

With Azure AD B2C there's also a comment about this: "Recommended only if the application has a single page architecture (SPA), has no backend components, or invokes a Web API via JavaScript. " - which isn't the case with the ASP.NET Core Web app template.

I think this code generation should be changed. I don't know when App registrations comes out of preview with Azure, but then this will be a bigger issue.

Going forward with 5.0 Azure will own the middleware and UI for this, so it's all in their hands now.

@blowdart - Thanks for the information. Is there a GitHub repo for this?

@AshTappin ...

I wasn't providing a client ID in the scopes parameter so an access token wasn't being returned hence the message.

Could you add the exact (code) fix that you used? I hit the same problem here.

Was this page helpful?
0 / 5 - 0 ratings