как использовать политику с JWT для авторизации - PullRequest
0 голосов
/ 26 апреля 2020

Я перешел по ссылке ниже для аутентификации токена JWT и ASP.NET CORE 3.1 IDENTITY. https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login

Затем я хотел управлять своими контроллерами, используя политику, такую ​​как конфигурация в Startup.cs коде ниже. Когда я его декодирую, он показывает api_access. Чего я хочу добиться - когда пользователь входит в систему, я хочу проверить, является ли пользователь администратором, а затем создать токен для admin и admin policy, если роль user, а затем сделать user policy , Я получаю роль и проверяю, является ли роль user или admin при создании удостоверения личности. И я попробовал с Почтальоном после помещения строки [Authorize(Policy = "Admin")] в контроллер, тогда я получаю ошибку ниже.

Ошибка

403 Запрещено

services.AddAuthorization(options =>
{
    options.AddPolicy("Admin", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Role, Constants.Strings.JwtClaims.Admin));
});
services.AddAuthorization(options =>
{
    options.AddPolicy("User", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Role, Constants.Strings.JwtClaims.User));
}); 

Константы

public static class Strings
{
    public static class JwtClaimIdentifiers
    {
        public const string Role = "role", Id = "id";
    }

    public static class JwtClaims
    {
        public const string Admin = "admin";
        public const string User = "user";
        public const string Dashboard = "dashboard";
    }
}

Метод фабричной генерации JWT

 public async Task<string> GenerateEncodedToken(string userName, string role, 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.Role),
                 identity.FindFirst(Helpers.Constants.Strings.JwtClaimIdentifiers.Id)
            };

            var jwt = new JwtSecurityToken(
                issuer: _jwtOptions.Issuer,
                audience: _jwtOptions.Audience,
                claims: claims,
                notBefore: _jwtOptions.NotBefore,
                expires: _jwtOptions.Expiration,
                signingCredentials: _jwtOptions.SigningCredentials);

            var encodedJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

            return encodedJwt;
        }

        public ClaimsIdentity GenerateClaimsIdentity(string userName, string role, string id)
        {
            if (role == "admin")
            {
              return new ClaimsIdentity(new GenericIdentity(userName, "Token"), new[]
              {
                new Claim(Helpers.Constants.Strings.JwtClaimIdentifiers.Id, id),
                new Claim(Helpers.Constants.Strings.JwtClaimIdentifiers.Role, Helpers.Constants.Strings.JwtClaims.Admin)
              });
            }
            return new ClaimsIdentity(new GenericIdentity(userName, "Token"), new[]
            {
                new Claim(Helpers.Constants.Strings.JwtClaimIdentifiers.Id, id),
                new Claim(Helpers.Constants.Strings.JwtClaimIdentifiers.Role, Helpers.Constants.Strings.JwtClaims.User)
            });

        }


AuthController


// 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 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);  
}

private async Task<ClaimsIdentity> GetClaimsIdentity(string userName, string password)
{
    if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
        return await Task.FromResult<ClaimsIdentity>(null);

    // get the user to verifty
    var userToVerify = await _userManager.FindByNameAsync(userName); 
    IList<string> role = await _userManager.GetRolesAsync(userToVerify);

    if (userToVerify == null) return await Task.FromResult<ClaimsIdentity>(null);

    // check the credentials
    if (await _userManager.CheckPasswordAsync(userToVerify, password))
    {
        return await Task.FromResult(_jwtFactory.GenerateClaimsIdentity(userName, role[0], userToVerify.Id));
    }

    // Credentials are invalid, or account doesn't exist
    return await Task.FromResult<ClaimsIdentity>(null);
}
...