【问题标题】:JWT token with role. ASP.NET Core & AngularJS具有角色的 JWT 令牌。 ASP.NET 核心和 AngularJS
【发布时间】:2019-07-25 01:04:31
【问题描述】:

我有 JWT 令牌的工作示例。它工作得很好,当我将此令牌存储在 angularJS 中时,我可以使用属性 [Authorize] 转到 api 控制器。但是当我生成带有角色的令牌时,我无法转到属性 [Authorize(Roles = "Admin")]。据我所知,我的角色保存在令牌中,我不需要将请求的标头更改为 api。下面是我的代码

 public class AuthOptions
{
public const string ISSUER = "MyAuthServer"; 
public const string AUDIENCE = "http://localhost:51489/"; 
const string KEY = "mysupersecret_secretkey!123";   
public const int LIFETIME = 60; 
public static SymmetricSecurityKey GetSymmetricSecurityKey()
{
    return new SymmetricSecurityKey(Encoding.ASCII.GetBytes(KEY));
}

}

[HttpPost]
[AllowAnonymous]
[Route("login")]
public async Task Login([FromBody]LoginViewModel model)
{
    var identity = await GetIdentity(model.Email, model.Password);
    if (identity == null)
    {
        Response.StatusCode = 400;
        await Response.WriteAsync("Invalid username or password.");
        return;
    }

    var now = DateTime.UtcNow;

    var jwt = new JwtSecurityToken(
            issuer: AuthOptions.ISSUER,
            audience: AuthOptions.AUDIENCE,
            notBefore: now,
            claims: identity.Claims,
            expires: now.Add(TimeSpan.FromMinutes(AuthOptions.LIFETIME)),
            signingCredentials: new 
     SigningCredentials(AuthOptions.GetSymmetricSecurityKey(), 
 SecurityAlgorithms.HmacSha256));
    var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

    var response = new
    {
        access_token = encodedJwt,
        username = identity.Name,
    };


    Response.ContentType = "application/json";
    await Response.WriteAsync(JsonConvert.SerializeObject(response, new 
JsonSerializerSettings { Formatting = Formatting.Indented }));
    return;
}

 private async Task<ClaimsIdentity> GetIdentity(string username, string 
 password)
{

    var user = _db.User.FirstOrDefault(x => x.Email == username);

    if (user != null)
    {

        var checkPass = _userManager.CheckPasswordAsync(user, password);

        if (!checkPass.Result)
            return null;

        var userRoles = await _userManager.GetRolesAsync(user);

        string role = userRoles[0];

        var claims = new List<Claim>
        {
            new Claim(ClaimsIdentity.DefaultNameClaimType, user.Email),
            new Claim(ClaimsIdentity.DefaultRoleClaimType, role)
        };
        ClaimsIdentity claimsIdentity =
        new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType,
            ClaimsIdentity.DefaultRoleClaimType);
        return claimsIdentity;
    }


    return null;
}

启动

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.TokenValidationParameters = 
                newTokenValidationParameters
                {

                    ValidateIssuer = true,

                    ValidIssuer = AuthOptions.ISSUER,


                    ValidateAudience = true,

                    ValidAudience = AuthOptions.AUDIENCE,

                    ValidateLifetime = true,


                    IssuerSigningKey =AuthOptions.GetSymmetricSecurityKey(),

                    ValidateIssuerSigningKey = true,
                };
            });

使用 angularJS $cookies 存储

$http.defaults.headers.common['Authorization'] = 'Bearer ' + 
response.data.access_token;

这个属性是有效的

[Authorize]

这个属性不起作用

[Authorize(Roles = "Admin")]

【问题讨论】:

  • 我无法重现您的问题,请尝试使用以下步骤解决问题:1。在客户端记录access_toekn,解码看是否包含http://schemas.microsoft.com/ws/2008/06/identity/claims/role, 2.在浏览器中查看http请求,是否在请求中附加了Authorization和正确的token。可以重现您的问题的演示会很有帮助。
  • 你能通过 jwt.io 网站检查你的 jwt 访问令牌吗?检查该角色的声明是否存在。
  • 显示您的 Startup.cs 配置。确保您已在授权服务中映射策略。 services.AddAuthorization(options =&gt; { options.AddPolicy("TrainedStaffOnly", policy =&gt; policy.RequireClaim("CompletedBasicTraining")); });
  • prntscr.com/mspes4

标签: angularjs asp.net-core jwt asp.net-identity


【解决方案1】:

您将您的角色作为声明存储在令牌中。

您需要创建一个适用于您分配给令牌的角色声明的策略。

在您的 Startup.cs 中创建策略

services.AddAuthorization(options =>
{
    options.AddPolicy("Admin", policy => policy.RequireClaim("Role", "Admin"));
});

那么就可以使用这个授权属性[Authorize(Policy = "Admin")]

【讨论】:

  • 在我的创业公司中,我有这个prntscr.com/mspes4,但它没有帮助,也许我需要在另一个案例中写它
猜你喜欢
  • 2021-08-07
  • 2023-03-19
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 2020-08-24
  • 2020-04-28
  • 2019-04-04
  • 1970-01-01
相关资源
最近更新 更多