0
votes

The API client is using either JWT token issued by API itself (standard) or by Azure AD.

When I enable ONLY the custom (standard) bearer authentication, everything works perfectly, without any issues.

Also, when I enable ONLY the Azure AD bearer authentication, everything works perfectly, also.

When I enable both of them, one of them stops working.

Here is my setup of the .Net core API:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(BuildStandardJwtBearerOptions);
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)

private void BuildStandardJwtBearerOptions(JwtBearerOptions options)
{
    var settings = GetStandardTokenSettings(null);

    options.IncludeErrorDetails = true;
    options.RequireHttpsMetadata = false;
    options.SaveToken = true;

    var signingKeyBytes = Encoding.UTF8.GetBytes(settings.SecretKey);
    var signingKey = new SymmetricSecurityKey(signingKeyBytes);
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidIssuer = settings.Issuer,
        ValidAudience = settings.Issuer,
        IssuerSigningKey = signingKey
    };
}

Here is an example error for when client is sending Azure AD token:

Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Failed to validate the token.

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10500: Signature validation failed. No security keys were provided to validate the signature. at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters) at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AzureADJwtBearer was not authenticated. Failure message: IDX10500: Signature validation failed. No security keys were provided to validate the signature. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with {action = "List", controller = "Account"}. Executing action BookRental.Api.Controllers.AccountController.List (BookRental.Api) Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Information: Authorization failed. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'. Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes (). Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: AuthenticationScheme: AzureADJwtBearer was challenged. Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action BookRental.Api.Controllers.AccountController.List (BookRental.Api) in 7.1108ms Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 16.8394ms 401

How can I make those two types of tokens to work side by side?

1

1 Answers

0
votes

You can try to change the default policy of the authorization system by indicating both the authentication schemes :

services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddAzureADBearer(options => Configuration.Bind("AzureAd", options))
    .AddJwtBearer("scc", BuildStandardJwtBearerOptions); 

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

services
    .AddAuthorization(options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes(AzureADDefaults.BearerAuthenticationScheme, "scc")
            .Build();
    });