Я перешел по ссылке ниже для аутентификации токена 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);
}