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));
}
...
如果删除策略,我可以毫无问题地呼叫有问题的端点。
我做错了什么?
提前致谢
这里有多个问题。
在客户端凭据流中没有用户。该令牌不包含 sub
声明。这就是没有经过身份验证的用户的原因。这解释了未经授权的错误,它具有 HttpStatusCode 401。
过滤器强制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
{
我已经设置了一个 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));
}
...
如果删除策略,我可以毫无问题地呼叫有问题的端点。
我做错了什么?
提前致谢
这里有多个问题。
在客户端凭据流中没有用户。该令牌不包含
sub
声明。这就是没有经过身份验证的用户的原因。这解释了未经授权的错误,它具有 HttpStatusCode 401。过滤器强制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
{