ASP.NET Core 5 授权策略未检测到声明

Posted

技术标签:

【中文标题】ASP.NET Core 5 授权策略未检测到声明【英文标题】:ASP.NET Core 5 Authorization Policy not detecting claim 【发布时间】:2022-01-17 10:18:43 【问题描述】:

我正在使用 ASP.NET Core 5 和 Identity Framework 创建一个 Web API 来处理用户。我正在尝试添加要求用户拥有“canEdit”声明的授权策略。在我的启动类中,我在 ConfigureServices 方法中添加了以下代码:

services.AddAuthorization(options => 

    options.AddPolicy("IsUser", policy => policy.RequireAuthenticatedUser());
    options.AddPolicy("CanEdit", policy => policy.RequireClaim("canEdit"));

在我的配置类中,我有:

// some middleware

app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints => 

    endpoints.MapControllers()
);

我在我的控制器中使用了这个策略,如下所示:

[HttpGet("edit")]
[Authorize(Policy = "CanEdit")]
public async Task<IActionResult> EditSomething()

    \\Stuff here

“IsUser”政策有效,但“CanEdit”政策无效。我在 AspNetUserClaims 表中有一个带有“canEdit”声明的用户,但是当我尝试使用该用户登录时,我仍然收到 403 Forbidden 响应。我正在使用 JSON Web 令牌进行身份验证。我尝试将“canEdit”声明添加到 JWT 中的声明列表中,认为可能在令牌中检测到声明,但这也不起作用。我首先检查了用户是否拥有声明,通过使用

var userClaims = await _userManager.GetClaimsAsync(currentUser);

并且正确的声明显示。我尝试将策略添加到其他控制器中的其他方法中,并检查了声明的大小写和不同名称,但没有成功。 我在这里错过了什么以使“CanEdit”政策无法正常工作?

编辑: 如果有帮助,这就是我创建 JWT 的方法:

public async Task<string> CreateToken(AppUser user)
    
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["jwtSecret"]));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha512Signature);
        
        var claims = new List<Claim>
        
            new Claim(ClaimTypes.NameIdentifier, user.Id),
            new Claim(ClaimTypes.Name, user.DisplayName),
            new Claim(ClaimTypes.Email, user.Email)
        ;
        var userClaims = await _userManager.GetClaimsAsync(user);
        claims.AddRange(userClaims);

        var tokenDescriptor = new SecurityTokenDescriptor
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = creds
        ;

        var tokenHandler = new JwtSecurityTokenHandler();
        var token = tokenHandler.CreateToken(tokenDescriptor);
        return tokenHandler.WriteToken(token);
    

【问题讨论】:

你能分享一个满足CanEdit策略的示例jwt吗? 请使用具有 canEdit 声明的用户登录,然后在方法上使用 IsUser 并在该方法中添加 HttpContext.User 并在其上添加断点,然后检查当前用户是否具有 canEdit 声明 @GordonKhanhNg。我在帖子中添加了 JWT 代码。政策是否检查数据库中的 AspNetUserClaims 表或声明的 JWT? 【参考方案1】:

感谢@TarikGen 的建议,我检查了 HttpContext.User 中的声明并设法看到了问题。

我在 AspNetUserClaims 表中对“canEdit”的声明实际上有一个声明类型为“角色”,这是问题的根源。我所要做的就是将声明类型更改为“canEdit”来解决问题。

补充说明: 由于我的错误,我确实注意到“角色”似乎是声明类型的关键字,因为 HttpContext.User 中的声明列表显示声明类型为“http://schemas.microsoft.com/ws/2008/ 06/identity/claims/role”,而不仅仅是“角色”。经过检查,我发现,如果我将我的策略设置为 RequireClaim("role"),我就会因此而未经授权。

【讨论】:

以上是关于ASP.NET Core 5 授权策略未检测到声明的主要内容,如果未能解决你的问题,请参考以下文章

在 Asp.Net Core 的 Razor 页面中检查登录用户授权策略

关于 ASP.NET Core 中的授权

ASP.NET Core 使用 JWT 自定义角色/策略授权需要实现的接口

ASP.NET Core MVC 授权的扩展:自定义 Authorize Attribute 和 IApplicationModelProvide

在 ASP.NET Core 中的每个操作之前查询数据库以获得角色授权

如何使用 AuthorizationHandlerContext 在 ASP.NET Core 2 自定义基于策略的授权中访问当前的 HttpContext