【发布时间】: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 => { options.AddPolicy("TrainedStaffOnly", policy => policy.RequireClaim("CompletedBasicTraining")); }); -
prntscr.com/mspes4
标签: angularjs asp.net-core jwt asp.net-identity