Я попробовал некоторые примеры авторизации в asp core 2 с токенами jwt и идентификатором ядра asp. Я выполнил этот код https://github.com/SunilAnthony/SimpleSecureAPI, и он отлично работает.
Проблема заключается в авторизации на основе ролей. Я попробовал что-то вроде этого: http://www.jerriepelser.com/blog/using-roles-with-the-jwt-middleware/
и результат странный. Мой метод управления:
[HttpGet]
[Authorize]
public IActionResult Get()
{
IEnumerable<Claim> claims = User.Claims; // contains claim with Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role" and Value = "Administrator"
bool role = User.IsInRole("Administrator"); // true
bool claim = User.HasClaim(ClaimTypes.Role, "Administrator"); // true
return Ok(claims);
}
Когда я вызываю эту конечную точку только с атрибутом [Authorize]
и проверяю роль/претензии в коде для текущего пользователя, это кажется хорошим (оба проверки истинны), но когда я изменил свой атрибут авторизации на [Authorize(Roles = "Administrator")]
он не работает → когда я вызываю эту конечную точку с этим атрибутом, я получаю 404. Я не знаю, где проблема. Мой класс запуска совершенно такой же, как в ссылке git выше, и я только что добавил список имен ролей строк в полезной нагрузке access_token внутри массива "ролей":
Он жестко закодирован, но я изменил свой метод входа только для теста следующим образом:
[HttpPost("login")]
public async Task<IActionResult> SignIn([FromBody] Credentials Credentials)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(Credentials.Email, Credentials.Password, false, false);
if (result.Succeeded)
{
IdentityUser user = await _userManager.FindByEmailAsync(Credentials.Email);
List<string> roles = new List<string>();
roles.Add("Administrator");
return new JsonResult(new Dictionary<string, object>
{
{ "access_token", GetAccessToken(Credentials.Email, roles) },
{ "username", user.Email },
{ "expired_on", DateTime.UtcNow.AddMinutes(_tokenLength) },
{ "id_token", GetIdToken(user) }
});
}
return new JsonResult("Unable to sign in") { StatusCode = 401 };
}
return new JsonResult("Unable to sign in") { StatusCode = 401 };
}
И метод GetAccessTokenMethod
:
private string GetAccessToken(string Email, List<string> roles)
{
var payload = new Dictionary<string, object>
{
{ "sub", Email },
{ "email", Email },
{ "roles", roles },
};
return GetToken(payload);
}
Где проблема с атрибутом [Authorize(Roles = "Administrator")]
?
Проблема с типом претензии:
http://schemas.microsoft.com/ws/2008/06/identity/claims/role
Каким-то образом атрибут [Authorize]
не работает при использовании со значением Roles
. Так что это [Authorize(Roles = "Administartor")]
не работает. Вы должны сопоставить тип заявки только с role
, применив преобразование к классу Startup
.
Если у вас есть Owin
основе Owin
:
app.UseClaimsTransformation(incoming =>
{
// either add claims to incoming, or create new principal
var appPrincipal = new ClaimsPrincipal(incoming);
if (appPrincipal.HasClaim(x => x.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"))
{
var value = appPrincipal.Claims.First(x =>
x.Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/role").Value;
incoming.Identities.First().AddClaim(new Claim("role", value));
}
return Task.FromResult(appPrincipal);
});