【问题标题】:Identity server: Authorization api returning 401身份服务器:授权 api 返回 401
【发布时间】:2020-11-26 22:26:12
【问题描述】:

我正在尝试使用 jwt 令牌来授权我的 api 上的请求。

到目前为止,我得到了 401

我尝试使用 jwt.io 来解码令牌,并且范围看起来不错

这可能与“权威”有关吗?

这就是我的授权标头请求的样子

我正在使用 Fiddler 来附加标题

授权标头

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

启动

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 }));
    }
}

【问题讨论】:

    标签: c# .net asp.net-core asp.net-web-api identityserver4


    【解决方案1】:

    您是否在 Startup.Configure 方法中添加了以下内容?

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

    你能把那个方法也加到问题中吗?

    如果您收到 404,那么我怀疑 URL 不正确,如果您有一些令牌问题,您应该收到 401 或 403。

    请求中的完整 URL 是什么样的?我认为您的网址有问题。

    您发布的令牌包含以下范围:

    “范围”:[ “开放”, “轮廓”, “电子邮件”, “api.read” ],

    但是您的操作方法包含: [授权(政策=“消费者”)]

    这要求一个不在令牌中的范围。

    要获得匹配的角色声明,您需要添加:

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

    【讨论】:

    • 我已经编辑了我的问题,我没有收到 404,抱歉。我添加了 Startup.Configure。我添加了app.UseAuthentication();,现在错误是 403(禁止)。我打电话的网址是http://localhost:5050/api/values
    • 但是如果我将它从[Authorize(Policy = "Consumer")] 更改为[Authorize(Roles = "Consumer")],它不应该工作吗?它没有
    • 使用 [Authorize("ApiReader") ] 代替,这就是令牌的目标及其与令牌范围匹配的策略。"roles" 将不匹配,因为 ASP.NET 角色名称和声明角色名称不一样。请参阅我关于角色声明的更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    相关资源
    最近更新 更多