Nelladel
Nelladel

Reputation: 188

.NET Core Authorization - Constant 403 on JWT Bearer

I'm attempting to authorize requests to my API which bear a JWT token attached to it, however, none of the tutorials, blog posts, and documentation have helped avoiding a constant 403 - Unauthorized error.

This is the -skimmed- current configuration:

Class which generates the token: TokenManagement.cs:

// Add the claims to the token
var claims = new[] {
    new Claim(JwtRegisteredClaimNames.Sub, credentials.Username),
    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
    new Claim("claimName", "claimValue")
};

Configuring the services: Startup.cs - ConfigureServices():

services.Configure<GzipCompressionProviderOptions>(options => options.Level = System.IO.Compression.CompressionLevel.Optimal);
services.AddResponseCompression();

services.AddAuthentication()
    .AddJwtBearer(config => {
        config.RequireHttpsMetadata = false;
        config.SaveToken = true;
        config.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidIssuer = "Issuer",
            ValidAudience = "Audience",
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(symmetricKey))
        };
});

services.AddAuthorization(options => {
    options.AddPolicy("myCustomPolicy", policy => {
        policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
        policy.RequireClaim("claimName", "claimValue");
    });
});

services.AddMvc();

General Configuration: Startup.cs - Configure():

app.UseAuthentication();

app.Use(async (context, next) => {
    await next();

    if (context.Response.StatusCode == 404 &&
        !Path.HasExtension(context.Request.Path.Value)) {
        context.Request.Path = "/index.html";
        await next();
    }
});

app.UseMvc();

app.UseResponseCompression();

app.UseDefaultFiles();
app.UseStaticFiles();

Controller which should be authorized: ActionsController.cs:

[Authorize(Policy = "myCustomPolicy")]
[Route("api/[controller]")]
public class ActionsController : Controller

Any request I send to the server (which carries a JWT token with the proper claim), returns as a 403.

Any methods which have the [AllowAnonymous] attribute, work just fine.

Is there a way to -at least- debug and see what's going on?

Upvotes: 3

Views: 4426

Answers (2)

Jack Ng
Jack Ng

Reputation: 493

I found out that some claim types changed to different values from my identity server config.

for example , In my Identity Server i am using role claim type:

  UserClaims = new []
  {
     JwtClaimTypes.Role , user.role // "JwtClaimTypes.Role" yield "role"
  };

But when i debuged my web api , the role claim type has changed to (see my snapshot below, under watch section):

 "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"

Solution:

To "workaround" (is this desired behavior?) the issue, you need to check your claim type value are planning use in web api, and use the correct claim type value in your policy.

 services.AddAuthorization(options =>
 {
    options.AddPolicy("RequireAdmin", policy =>
    {
        
       //policy.RequireClaim(IdentityModel.JwtClaimTypes.Role, "Admin"); // this doesn't work
       policy.RequireClaim(ClaimTypes.Role, "Admin"); //  this work
    });
  });

my web api debug snapshot:

screen of policyAssertion

Upvotes: 2

Saveen
Saveen

Reputation: 712

Try to enable CORS in Startup.cs File

public void ConfigureAuth(IAppBuilder app) {
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    // Rest of code
}

Upvotes: 0

Related Questions