Bearer 被 IdentityServer4 中的授权过滤器禁止
Bearer was forbidden with Authorize filter in IdentityServer4
在测试 IdentityServer4 with AspNetAuthorization 教程时,我添加了一个简单的 [Authorize(Roles = "Administrator")]
,从那以后我得到了这个错误:
AuthenticationScheme: Bearer was forbidden.
我的用户有这样的声明:
new Claim(ClaimTypes.Role, "Administrator", ClaimValueTypes.String)
.
在ConfigureServices
方法中:
services.AddAuthorization(options =>
{
options.AddPolicy("AdministratorOnly", policy => policy.RequireRole("Administrator"));
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
在Configure
方法中:
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
{
Authority = "http://localhost:5000",
ScopeName = "openid",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
RequireHttpsMetadata = false,
});
调试输出:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Debug: Executing action LearningEntityServer4.OAuth.ValuesController.Get (LearningEntityServer4.OAuth)
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myuser.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed for user: myuser.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Warning: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult: Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware: Information: AuthenticationScheme: Bearer was forbidden.
我在配置中遗漏了什么?
PS:我已经检查过 所以 post 没有成功。
根据附加资源,您实际上应该将策略名称放在授权属性中,就像这样 [Authorize("AdministratorOnly")]
。
我终于抽出时间写下声明世界中角色检查如何工作的内部原理:
https://leastprivilege.com/2016/08/21/why-does-my-authorize-attribute-not-work/
简而言之 - 确保您用于角色的声明类型与您的 ClaimsIdentity 上的 RoleClaimType 相匹配。或者在您的策略中将 RequireRole
替换为 RequireClaim
并使用正确的类型。
事实上,我在阅读@leastprivilege 详细回答之前解决了我的问题。
问题出在声明类型的命名上,
我更改了以下内容:
new Claim(ClaimTypes.Role, "Administrator");
对此:
new Claim(JwtClaimTypes.Role, "Administrator");
并且授权有效。那是因为它们之间的基础字符串值不同,我的配置期望 "role" 一个:
ClaimTypes.Role => "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
JwtClaimTypes.Role => "role"
或者根据他的回答可以做到这一点:
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
{
Authority = "http://localhost:5000",
ScopeName = "scope",
ScopeSecret = "secret",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
RequireHttpsMetadata = false,
RoleClaimType = "role"
});
其背后的详细原因,请阅读@leastprivilege 的回答
在测试 IdentityServer4 with AspNetAuthorization 教程时,我添加了一个简单的 [Authorize(Roles = "Administrator")]
,从那以后我得到了这个错误:
AuthenticationScheme: Bearer was forbidden.
我的用户有这样的声明:
new Claim(ClaimTypes.Role, "Administrator", ClaimValueTypes.String)
.
在ConfigureServices
方法中:
services.AddAuthorization(options =>
{
options.AddPolicy("AdministratorOnly", policy => policy.RequireRole("Administrator"));
});
services.AddMvc(config =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
config.Filters.Add(new AuthorizeFilter(policy));
});
在Configure
方法中:
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
{
Authority = "http://localhost:5000",
ScopeName = "openid",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
RequireHttpsMetadata = false,
});
调试输出:
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Debug: Executing action LearningEntityServer4.OAuth.ValuesController.Get (LearningEntityServer4.OAuth)
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization was successful for user: myuser.
Microsoft.AspNetCore.Authorization.DefaultAuthorizationService: Information: Authorization failed for user: myuser.
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker: Warning: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
Microsoft.AspNetCore.Mvc.ChallengeResult: Information: Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerMiddleware: Information: AuthenticationScheme: Bearer was forbidden.
我在配置中遗漏了什么?
PS:我已经检查过
根据附加资源,您实际上应该将策略名称放在授权属性中,就像这样 [Authorize("AdministratorOnly")]
。
我终于抽出时间写下声明世界中角色检查如何工作的内部原理:
https://leastprivilege.com/2016/08/21/why-does-my-authorize-attribute-not-work/
简而言之 - 确保您用于角色的声明类型与您的 ClaimsIdentity 上的 RoleClaimType 相匹配。或者在您的策略中将 RequireRole
替换为 RequireClaim
并使用正确的类型。
事实上,我在阅读@leastprivilege 详细回答之前解决了我的问题。
问题出在声明类型的命名上,
我更改了以下内容:
new Claim(ClaimTypes.Role, "Administrator");
对此:
new Claim(JwtClaimTypes.Role, "Administrator");
并且授权有效。那是因为它们之间的基础字符串值不同,我的配置期望 "role" 一个:
ClaimTypes.Role => "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
JwtClaimTypes.Role => "role"
或者根据他的回答可以做到这一点:
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions()
{
Authority = "http://localhost:5000",
ScopeName = "scope",
ScopeSecret = "secret",
AutomaticAuthenticate = true,
AutomaticChallenge = true,
RequireHttpsMetadata = false,
RoleClaimType = "role"
});
其背后的详细原因,请阅读@leastprivilege 的回答