2

Porting from .NET Core 3 to .NET Core 5 Authentication, I am required to replace services.AddSignIn (deprecated) by services.AddMicrosoftIdentityWebAppAuthentication or other related MicrosoftIdentity extensions. I need to support both OpenId user login and Bearer token policies for API access. These both worked with services.AddSignIn but I can't get this combination working with the new MicrosftIdentity extensions.

I have a .Net Core Blazor Server with OpenId login to Azure AD B2C. This works fine as:

            services.AddMicrosoftIdentityWebAppAuthentication(
            configuration,
            aadB2CConfigName,
            OpenIdConnectDefaults.AuthenticationScheme,
            CookieAuthenticationDefaults.AuthenticationScheme,
            true);

But when I add the Bearer Token handling directly after it, as follows, then it overrides the OpenId, so only the Bearer API works (and vice versa):

            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApi(
                options =>
                {
                    configuration.Bind("AzureAd", options);

                    options.ForwardDefaultSelector = ctx =>
                        ctx.Request.Path.StartsWithSegments("/api", System.StringComparison.InvariantCulture)
                            ? JwtBearerDefaults.AuthenticationScheme
                            : null;

                    options.Authority = configuration["AzureAd:Authority"];
                    options.TokenValidationParameters.NameClaimType = "name";
                    options.TokenValidationParameters.RoleClaimType = "roles";

                }, options =>
                {
                    configuration.Bind(aadB2CConfigName, options);
                });

For completeness, followed by (worked fine in .net core 3)

        services.AddControllersWithViews()
            .AddMicrosoftIdentityUI();

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Tst1AuthPolicy", policy => policy.RequireRole("Tst1AppRole"));
            options.AddPolicy("Tst2AuthPolicy", policy => policy.RequireRole("Tst2AppRole"));
        });

The chaining of extension methods does not seem to work as it did with AddSignIn. How do I make both of these work again in parallel in the new .net core 5 context? i.e. OpenId as default, and Bearer Tokens when the WebApi (/api) is hit.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
GGleGrand
  • 1,565
  • 1
  • 20
  • 45

2 Answers2

1

Got it working as follows. I don't feel totally confident that this is the intended/best usage here, but it works:

Replace the above "null" as follows with the alternate login scheme, which is the oreo cookie scheme in our case:

options.ForwardDefaultSelector = ctx =>
ctx.Request.Path.StartsWithSegments("/api", System.StringComparison.InvariantCulture)
    ? JwtBearerDefaults.AuthenticationScheme
    : CookieAuthenticationDefaults.AuthenticationScheme;

This will probably mean that, instead of a HTTP-Status error, I get a HTML login page if the Bearer Token fails, so there must be a better way ... if anybody cares to chime in.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
GGleGrand
  • 1,565
  • 1
  • 20
  • 45
0

Have you tried explicitly calling out the authentication scheme on the controllers?

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] 
[Microsoft.AspNetCore.Components.Route("api/[Controller]")]
[ApiController]
public class LoginController :ControllerBase
{

}
gwruck
  • 341
  • 2
  • 9