JWT токен с ролью.ASP.NET Core & AngularJS - PullRequest
0 голосов
/ 03 марта 2019

У меня есть рабочий пример токена JWT.Это хорошо работает, и когда я помещаю этот токен в хранилище в angularJS, я могу перейти к контроллеру API с атрибутом [Authorize].Но когда я генерирую токен с ролью, я не могу перейти к атрибуту [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 Ответ

0 голосов
/ 03 марта 2019

Вы сохраняете свою роль в качестве заявки в токене.

Вам потребуется создать политику, которая будет работать с заявкой на роль, назначенной для вашего токена.

Создатьполитика в вашей Startup.cs

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

Тогда вы можете использовать этот атрибут авторизации [Authorize(Policy = "Admin")]

...