IdentityServer4 授权失败,全局授权策略

IdentityServer4 Authorization failed with global authorization policy

我已经设置了一个 API 既充当身份验证/授权服务,又同时公开一些端点以进行数据检索。

API 是用 IdentityServer4 设置的。我可以通过客户端凭据成功检索访问令牌。但是,当我尝试使用检索到的令牌调用受保护端点时,我收到 404 not found。日志显示请求未经授权。

我怀疑与我添加授权策略的方式有关。它应该全局应用于所有控制器,使用我在 AddAuthentication() 中应用的默认身份验证方案,如下所示:

    IdentityModelEventSource.ShowPII = true;

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => 
    {
        options.Authority = "http://localhost";
        options.RequireHttpsMetadata = false;
        options.Audience = "identityService";
    }).AddMvc(options => 
    {
       var policy = new AuthorizationPolicyBuilder()
          .RequireAuthenticatedUser()
          .Build();

       options.Filters.Add(new AuthorizeFilter(policy));
    }
    ...

如果删除策略,我可以毫无问题地呼叫有问题的端点。

我做错了什么?

提前致谢

这里有多个问题。

  1. 在客户端凭据流中没有用户。该令牌不包含 sub 声明。这就是没有经过身份验证的用户的原因。这解释了未经授权的错误,它具有 HttpStatusCode 401。

  2. 过滤器强制authorization所有方法。当未经授权的用户访问某个方法时,这将导致 HttpStatusCode 404。这意味着某些方法必须对匿名用户保持可用。您可以通过将 最低 级别的 AllowAnonymous 属性设置为从全局授权中排除方法。

例如家庭控制器:

[AllowAnonymous]
public IActionResult Error()
{

对于客户端凭据流,您可能希望将过滤器更改为令牌的一部分,例如范围:

var policy = new AuthorizationPolicyBuilder()
                .RequireClaim("scope", "MyScope").Build();

尽管当您混合使用功能(来自 IdentityServer 和 Api)时,这可能不适合作为全局过滤器。

相反,您可以配置策略和使用属性。启动中:

Services.AddAuthorization(option =>
{
    option.AddPolicy("MyScopePolicy", p => p.RequireScope("MyScope"));
}

在控制器中:

[Authorize("MyScopePolicy")]
[ApiController]
public class MyController : ControllerBase
{