具有 jwt 令牌和身份的 asp core 2 中基于角色的授权

Posted

技术标签:

【中文标题】具有 jwt 令牌和身份的 asp core 2 中基于角色的授权【英文标题】:Role based authorization in asp core 2 with jwt tokens and identity 【发布时间】:2018-04-10 16:12:15 【问题描述】:

我在 asp core 2 中尝试了一些带有 jwt 令牌和 asp 核心身份的授权示例。我已按照此代码https://github.com/SunilAnthony/SimpleSecureAPI 进行操作,并且工作正常。

问题在于基于角色的授权。我试过这样的事情: http://www.jerriepelser.com/blog/using-roles-with-the-jwt-middleware/

结果很奇怪。 我的控制器方法:

[HttpGet]
[Authorize]
public IActionResult Get()

    IEnumerable<Claim> claims = User.Claims; // contains claim with Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" and Value = "Administrator"
    bool role = User.IsInRole("Administrator"); // true
    bool claim = User.HasClaim(ClaimTypes.Role, "Administrator"); // true

    return Ok(claims);
 

当我仅使用属性 [Authorize] 调用此端点并检查当前用户的代码中的角色/声明时,它看起来不错(两项检查都是正确的),但是当我将授权属性更改为 [Authorize(Roles = "Administrator")] 时,它不起作用-> 当我用这个属性调用这个端点时,我会收到 404。我不知道问题出在哪里。我的启动类与上面的 git 链接完全相同,我刚刚在 access_token 的有效负载中添加了字符串角色名称列表,然后是“角色”数组:

它是硬编码的,但我已经更改了我的登录方法,只是为了进行这样的测试:

[HttpPost("login")]
public async Task<IActionResult> SignIn([FromBody] Credentials Credentials)

    if (ModelState.IsValid)
    
        var result = await _signInManager.PasswordSignInAsync(Credentials.Email, Credentials.Password, false, false);
        if (result.Succeeded)
        
            IdentityUser user = await _userManager.FindByEmailAsync(Credentials.Email);

            List<string> roles = new List<string>();
            roles.Add("Administrator");

            return new JsonResult(new Dictionary<string, object>
                
                     "access_token", GetAccessToken(Credentials.Email, roles) ,
                     "username", user.Email ,
                     "expired_on", DateTime.UtcNow.AddMinutes(_tokenLength) ,
                     "id_token", GetIdToken(user) 
                );
        
        return new JsonResult("Unable to sign in")  StatusCode = 401 ;
    
    return new JsonResult("Unable to sign in")  StatusCode = 401 ;

还有GetAccessTokenMethod

private string GetAccessToken(string Email, List<string> roles)

  var payload = new Dictionary<string, object>
  
     "sub", Email ,
     "email", Email ,
     "roles", roles ,
  ;
  return GetToken(payload);

[Authorize(Roles = "Administrator")] 属性的问题在哪里?

【问题讨论】:

您是否检查过端点是否真的在返回重定向?您的授权检查似乎失败,然后可能试图将您重定向到丢失的登录页面。 问题不是 404(是的,我没有登录页面),而是我的用户具有角色/声明“管理员”但我不知道如何配置角色的情况基于使用属性 [Authorize(Roles = "Administrator")] 的授权。目前,即使他有这个角色,同一个用户也会得到 404。类似的问题在这里描述了***.com/questions/45915929/… 【参考方案1】:

问题在于声明的类型:

http://schemas.microsoft.com/ws/2008/06/identity/claims/role

不知何故,[Authorize] 属性在与Roles 值一起使用时无法正常工作。 所以这个[Authorize(Roles = "Administartor")] 不起作用。 您必须通过对 Startup 类应用转换将声明类型仅映射到 role

如果您有一个基于 Owin 的项目:

app.UseClaimsTransformation(incoming =>
            
                // either add claims to incoming, or create new principal
                var appPrincipal = new ClaimsPrincipal(incoming);
                if (appPrincipal.HasClaim(x => x.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"))
                
                    var value = appPrincipal.Claims.First(x =>
                        x.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role").Value;

                    incoming.Identities.First().AddClaim(new Claim("role", value));
                                

                return Task.FromResult(appPrincipal);
            );

【讨论】:

以上是关于具有 jwt 令牌和身份的 asp core 2 中基于角色的授权的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 中的 Jwt 令牌身份验证

具有用户权限的基于 JWT 令牌的授权 Asp.net core 2.0

ASP Core 3.0 API 令牌自定义令牌身份验证(不是 jwt!)

ASP.net Core 2.0 JWT 令牌刷新

从 ASP.NET Core 中的 API 读取 JWT 令牌

如何使用 Microsoft 身份平台身份验证在 ASP.NET Core Web 应用程序中获取 JWT 令牌?