【问题标题】:How do I make and use JWT role based authentication?如何制作和使用基于 JWT 角色的身份验证?
【发布时间】:2020-08-06 09:51:33
【问题描述】:

我按照下面的教程链接。

https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login

我正在尝试了解它是如何工作的,并且我想使用此令牌使用基于角色的身份验证。所以我在Startup.cs 文件中制定了另一项政策,如下所示。

我尝试在控制器中像[Authorize(Policy = "admin")][Authorize(Policy = "ApiUser")] 一样使用它,但每次我尝试使用postman 时都会得到unauthenticated。 我错过了什么?如何根据教程进行基于角色的身份验证?

启动

services.AddAuthorization(options =>
{
    options.AddPolicy("ApiUser", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess));
});
services.AddAuthorization(options =>
    options.AddPolicy("admin", policy => policy.RequireRole("admin"))
);


身份验证控制器

// POST api/auth/login
[HttpPost("login")]
public async Task<IActionResult> Post([FromBody]CredentialsViewModel credentials)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password);



    if (identity == null)
    {
        //return null;
        return BadRequest(Error.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
    }
    var id = identity.Claims.Single(c => c.Type == "id").Value; 
    var user = await _userManager.FindByIdAsync(id);
    IList<string> role = await _userManager.GetRolesAsync(user);
    var jwt = await Tokens.GenerateJwt(identity, role[0], _jwtFactory, credentials.UserName, _jwtOptions, new JsonSerializerSettings { Formatting = Formatting.Indented });


    return new OkObjectResult(jwt);

}

我尝试了所有方法,但都没有工作

[Authorize(Policy = "ApiUser")]
[HttpGet("getPolicy")]
public string GetPolicy()
{
    return "policyWorking";
}
[Authorize(Roles = "admin")]
[HttpGet("getAdmin")]
public string GetAdmin()
{
    return "adminWorking";
}
[Authorize ]
[HttpGet("getAuthorize")]
public string GetAuthorize()
{
    return "normal authorize Working";
}

【问题讨论】:

    标签: asp.net asp.net-core asp.net-core-3.1 asp.net-roles asp.net-authentication


    【解决方案1】:

    我使用this 教程制作了我的。

    它也适用于 .Net Core 3.1。

    @更新

    我正在为此使用政策:

    services.AddAuthorization(options => {
        options.AddPolicy(Policies.RequireAny, policy =>
            policy.RequireClaim(JwtClaimTypes.Role, Enum.GetNames(typeof(AvailableRoles))));
        options.AddPolicy(Policies.RequireAdmin, policy =>
            policy.RequireClaim(JwtClaimTypes.Role,
                AvailableRoles.Admin.ToString()));
    });
    

    在控制器中

    [HttpDelete("{id:int:min(1)}")]
    [Authorize(Policy = Policies.RequireAdmin)]
    public async Task<IActionResult> Delete(int id) {
        // CODE
        return Ok();
    }
    

    并在创建 JWT 令牌时:

    
    // Other claims and code...
    
    claims.Add(new Claim(JwtClaimTypes.Role, roles[0]))
    var token = new JwtSecurityToken(
        issuer:_appSettings.AppUrl,
        audience:_appSettings.AppUrl,
        claims: claims,
        expires: expires,
        signingCredentials: credentials
    );
    
    return new JwtSecurityTokenHandler().WriteToken(token);
    

    【讨论】:

    • 假设你可以使用token获取数据,那么你如何使用角色呢?限制访问?你能分享一下你是怎么做到的吗?
    • 我完全按照,它不工作 401 未经授权
    • 添加了更多说明
    【解决方案2】:

    首先,请确保您在 appsettings.json 中添加了 json 字符串,否则您将始终得到 401 unauthorized

    "JwtIssuerOptions": {
        "Issuer": "webApi",
        "Audience": "http://localhost:5000/"
    }
    

    我错过了什么?如何根据教程进行基于角色的身份验证?

    1.如果您想使用以下方式注册服务:

    services.AddAuthorization(options =>
        options.AddPolicy("admin", policy => policy.RequireRole("admin"))
    );
    

    authorize 属性应如下所示:

    [Authorize(Policy  = "admin")]
    

    2.如果你想使用以下方式:

    [Authorize(Roles = "admin")]
    

    您需要从 Startup.cs 中删除该服务:

    //services.AddAuthorization(options =>
    //    options.AddPolicy("admin", policy => policy.RequireRole("admin"))
    //);
    

    然后,不要忘记在JwtFactory.GenerateEncodedToken 中添加具有角色的声明,如下所示:

    public async Task<string> GenerateEncodedToken(string userName, ClaimsIdentity identity)
    {
        var claims = new[]
        {
                new Claim(JwtRegisteredClaimNames.Sub, userName),
                new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
                new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64),
                identity.FindFirst(Helpers.Constants.Strings.JwtClaimIdentifiers.Rol),
                identity.FindFirst(Helpers.Constants.Strings.JwtClaimIdentifiers.Id),
                new Claim(ClaimTypes.Role,"admin")
        };
            //...
    }
    

    【讨论】:

    • Here 是我的整个项目。
    • 这里的“aaa”是什么?哦,天哪!!! appsetting.json!!这是问题所在!
    • 当我这样做时 //services.AddAuthorization(options => // options.AddPolicy("admin", policy => policy.RequireRole("admin")) //);如何设置角色并使用它?你的github有例子吗?无论如何,非常感谢你
    • 那是“admin”,我修改了。如果我的回答对你有帮助,你能accept as answer
    • 我能问最后一件事吗?如何区分 admin 和 apiUser?它是如何制作的?现在登录时自动为apiuser,那么我该如何制定其他策略并使用它?你有例子或任何文章吗?
    猜你喜欢
    • 2016-05-01
    • 1970-01-01
    • 2017-11-17
    • 2020-07-29
    • 1970-01-01
    • 2016-01-03
    • 2013-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多