Search code examples
c#.netasp.net-coreasp.net-web-apiidentityserver4

Identity server: Authorization api returning 401


I'm trying to use a jwt token in order to authorize request on my api.

So far I'm getting 401

I tried used jwt.io in order to decode the token, and the scopes look ok

May be that something to do with the 'Authority'?

This is how my authorization header request looks like

I'm using Fiddler in order to attach the header

Authorization header

Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImRiZDk4YWI3MjQ2YWM1ZDQ4YTkwNjE3NjQzNjdmZDIxIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE1OTY3Mjc1NzMsImV4cCI6MTU5NjczMTE3MywiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoicmVzb3VyY2VhcGkiLCJjbGllbnRfaWQiOiJhbmd1bGFyX3NwYSIsInN1YiI6IjhlNzAxZDMyLWEzOTAtNGIzYS05MDA0LTRmMDI5OTMxMTNkYyIsImF1dGhfdGltZSI6MTU5NjcyNzU3MiwiaWRwIjoibG9jYWwiLCJnaXZlbl9uYW1lIjoidGVzdDEyIiwiZW1haWwiOiJ0ZXN0MTJAZ21haWwuY29tIiwiaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93cy8yMDA4LzA2L2lkZW50aXR5L2NsYWltcy9yb2xlIjoiY29uc3VtZXIiLCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIiwiZW1haWwiLCJhcGkucmVhZCJdLCJhbXIiOlsicHdkIl19.rKf1DxfYMC8_7tllZ5Ft_LTwx2zBREDdlVqxEi-j7qoPakocOKd_Rwo8KvLbHa80oe6F33i2G5K2nuBUDO9jDm9SrU7UmymIwSFj0gsOjhQ-IJvUlhGBrx0TSoqTjTEgkdP9o3XHzqvea-vqcyfQNMR1QhFdFSz9JZgvD2uiOaN7rpx1J3tZvBS5FRx9058LqrCOFJpkjUAChx-WGZlDdUfE7WH8qeUB0AYup3oeeTYM9zEZ60IH001g8S3P1HBAI3SK-JpX1QbC5JioEWx9VaDo9elNYbiyXVFLJzCspwatUd6Y1YD5La27oI82PM84l9K9-pvRyEf76v1Il_YG1g

Startup

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(o =>
    {
        o.Authority = "http://localhost:5000";
        o.Audience = "resourceapi";
        o.RequireHttpsMetadata = false;
    });

    services.AddAuthorization(options =>
    {
        options.AddPolicy("ApiReader", policy => policy.RequireClaim("scope", "api.read"));
        options.AddPolicy("Consumer", policy => policy.RequireClaim(ClaimTypes.Role, "consumer"));
    });

    services.AddControllers();
}

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {

        app.UseCors("EnableCORS");

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

Api

[Authorize(Policy = "ApiReader")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{

    [Authorize(Policy = "Consumer")]
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new JsonResult(User.Claims.Select(c => new { c.Type, c.Value }));
    }
}

Solution

  • Have you added the following in your Startup.Configure method?

            app.UseAuthentication();
            app.UseAuthorization();
    

    Can you add that method to the question as well?

    If you get a 404, then I suspect the URL is not correct, you should have received a 401 or 403 if you had some token issues.

    What does the complete URL in the request look like? I think you have a problem with that URL.

    The token you are posting cotains the following scopes:

    "scope": [ "openid", "profile", "email", "api.read" ],

    But your action method contains: [Authorize(Policy = "Consumer")]

    That asks for a scope that is not in the token.

    To get the role claim to match you need to add:

    options.TokenValidationParameters = new TokenValidationParameters
    {
          RoleClaimType = JwtClaimTypes.Role,
    };