Authorize Policy 属性总是返回 403 禁止使用 .net core Identity 和 JwtBearerAuthentication
Posted
技术标签:
【中文标题】Authorize Policy 属性总是返回 403 禁止使用 .net core Identity 和 JwtBearerAuthentication【英文标题】:Authorize Policy attribute always returns 403 forbidden using .net core Identity and JwtBearerAuthentication 【发布时间】:2017-11-17 06:12:26 【问题描述】:在this guide 之后,我能够使用
进行身份验证Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.AspNetCore.Authentication.JwtBearer
现在我正在尝试使用角色或声明来保护我的 api 端点。我都试过了,结果相同(403)
仅使用 [Authorize]
即可。
我的代码目前看起来像这样:
控制器:
[Authorize(Policy = "RequireUserRole")]
// Also tried [Authorize(Roles="User")]
public string Get()
return "YO";
启动:
services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<ApplicationContext>();
services.Configure<JWTSettings>(Configuration.GetSection("JWTSettings"));
services.AddAuthorization(options =>
options.AddPolicy("RequireUserRole", policy => policy.RequireRole("User"));
);
...
app.UseIdentity();
var secretKey = Configuration.GetSection("JWTSettings:SecretKey").Value;
var issuer = Configuration.GetSection("JWTSettings:Issuer").Value;
var audience = Configuration.GetSection("JWTSettings:Audience").Value;
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));
app.UseJwtBearerAuthentication(new JwtBearerOptions
AutomaticAuthenticate = true,
AutomaticChallenge = true,
TokenValidationParameters = new TokenValidationParameters
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
// Validate the JWT Issuer (iss) claim
ValidateIssuer = true,
ValidIssuer = issuer,
// Validate the JWT Audience (aud) claim
ValidateAudience = true,
ValidAudience = audience,
ValidateLifetime = true
);
app.UseMvcWithDefaultRoute();
当我创建用户时,我将其分配给角色“用户”
await _userManager.AddToRoleAsync(user, "User");
角色关系创建成功,但到达端点时角色验证失败。
任何帮助表示赞赏!
【问题讨论】:
对我来说值得注意的是.RequrieClaim("role", "admin")
不起作用,.RequireRole("admin")
这样做了,感谢您给了我尝试的想法
我不得不为 Azure 应用程序授权更改角色声明类型:options.TokenValidationParameters.RoleClaimType = "schemas.microsoft.com/ws/2008/06/identity/claims/role";
【参考方案1】:
答案就在这个mdsn blog post:
基于角色的授权可通过 ASP.NET 开箱即用 身份。只要用于身份验证的不记名令牌包含 角色元素,ASP.NET Core 的 JWT 不记名身份验证中间件 将使用该数据为用户填充角色。
因此,基于角色的授权属性(如 [Authorize(Roles = "Manager,Administrator")] 来限制对管理员和管理员的访问) 可以 被添加到 API 并立即工作。
所以我在我的访问令牌对象中添加了一个名为角色的元素:
private string GetAccessToken(string userRole)
var payload = new Dictionary<string, object>
...
"roles", userRole
;
return GetToken(payload);
【讨论】:
我认为这在系统中是一种不好的做法,您可能会更改用户角色,并且用户之前登录过一次并且过期时间很长。【参考方案2】:我阅读了那个 msdn 帖子并在启动时添加了:
internal class HasRoleRequerementAuthHandler : AuthorizationHandler<HasRoleRequirement>
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, HasRoleRequirement requirement)
if (context.User.HasClaim(c => c.Type == JwtRegisteredClaimNames.NameId))
if (context.User.FindFirst(c => c.Type == JwtRegisteredClaimNames.Typ).Value == requirement.RoleName)
context.Succeed(requirement);
return Task.CompletedTask;
internal class HasRoleRequirement : IAuthorizationRequirement
public readonly string RoleName;
public HasRoleRequirement(string roleName)
RoleName = roleName;
然后添加策略:
opt.AddPolicy("Test", builder =>
builder.Requirements.Add(new HasRoleRequirement("User"));
);
我的令牌是这样生成的:
var claims = new List<Claim>
new Claim(JwtRegisteredClaimNames.NameId, user.Uid),
new Claim(JwtRegisteredClaimNames.Typ, type.ToString())
;
var creds = new SigningCredentials(_key, SecurityAlgorithms.HmacSha512Signature);
var tokenDesc = new SecurityTokenDescriptor
Subject = new ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(7),
SigningCredentials = creds
;
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDesc);
return tokenHandler.WriteToken(token);
然后我可以使用策略 Auth 标头:
[HttpGet("TestAuth")]
[Authorize(Policy = "Test")]
public IActionResult TestAuth()
return new OkResult();
【讨论】:
以上是关于Authorize Policy 属性总是返回 403 禁止使用 .net core Identity 和 JwtBearerAuthentication的主要内容,如果未能解决你的问题,请参考以下文章
Authorize(Roles = "Admin") 总是返回 ACCESS DENIED
Laravel 8 Policy 总是返回“此操作未经授权”。
sec:authorize 总是在浏览器中为百里香视图中的 isAuthenticated() 和 isAnonymous() 返回相同的视图
添加 Authorize 属性时 Web api 核心返回 404