Получите заявки от контроллера WebAPI - токена JWT,
Я создал приложение, которое использует аутентификацию на предъявителя JWT в ASP.NET Core. При аутентификации я определяю некоторые пользовательские требования, которые мне нужно прочитать в другом контроллере WebAPI, чтобы выполнить некоторые действия.
Любые идеи Как я могу это достичь?
Это выглядит как мой код: (код был упрощен)
public async Task<IActionResult> AuthenticateAsync([FromBody] UserModel user)
{
..............
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("userSecurityKey", userDeserialized.SecurityKey.ToString()),
new Claim("timeStamp",timeStamp),
new Claim("verificationKey",userDeserialized.VerificationKey.ToString())
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
.................
}
Другой контроллер: (Требуется прочитать требование "проверкаKey").
[HttpGet]
[Route("getcandidate")]
public async Task<IActionResult> GetCandidateAsync()
{
try
{
............
var verificationKey = //TODO: GET VerificationKey FROM THE TOKEN
var verificationRecord = await service.GetVerificationRecordAsync(verificationKey);
.................
}
catch (Exception)
{
return NotFound();
}
}
Ответы
Ответ 1
Вы должны иметь возможность получить такие претензии в контроллере
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
// or
identity.FindFirst("ClaimName").Value;
}
Если вы хотите, вы можете написать методы расширения для интерфейса IPrincipal и получить заявки, используя приведенный выше код, а затем получить их, используя (например)
HttpContext.User.Identity.MethodName();
Для полноты ответа. Чтобы декодировать токен JWT, напишите метод проверки токена и извлечения информации.
public static ClaimsPrincipal ValidateToken(string jwtToken)
{
IdentityModelEventSource.ShowPII = true;
SecurityToken validatedToken;
TokenValidationParameters validationParameters = new TokenValidationParameters();
validationParameters.ValidateLifetime = true;
validationParameters.ValidAudience = _audience.ToLower();
validationParameters.ValidIssuer = _issuer.ToLower();
validationParameters.IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.Secret));
ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(jwtToken, validationParameters, out validatedToken);
return principal;
}
Теперь мы можем проверить и извлечь претензии, используя:
ValidateToken(tokenString)?.FindFirst("ClaimName")?.Value
Следует отметить, что метод ValidateToken вернет null
значение, если проверка не удалась.
Ответ 2
// Cast to ClaimsIdentity.
var identity = HttpContext.User.Identity as ClaimsIdentity;
// Gets list of claims.
IEnumerable<Claim> claim = identity.Claims;
// Gets name from claims. Generally it an email address.
var usernameClaim = claim
.Where(x => x.Type == ClaimTypes.Name)
.FirstOrDefault();
// Finds user.
var userName = await _userManager
.FindByNameAsync(usernameClaim.Value);
if (userName == null)
{
return BadRequest();
}
// The rest of your code goes here...
Ответ 3
Существует несколько реализаций JWT для.NET Framework. Если вы используете System.IdentityModel.Tokens.Jwt, когда вы проверяете токен, вы получаете System.Security.Claims.ClaimsPrincipal, в котором хранятся заявки на токены в свойстве "Претензии". Таким образом, вы можете получить претензии на токен следующим образом:
string token = // ... read the token
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
TokenValidationParameters validationParameters = ...;
SecurityToken securityToken;
IPrincipal principal;
try
{
// token validation
principal = tokenHandler.ValidateToken(token, validationParameters, out securityToken);
// Reading the "verificationKey" claim value:
var vk = principal.Claims.SingleOrDefault(c => c.Type == "verificationKey").Value;
}
catch
{
principal = null; // token validation error
}
Теперь, где вы размещаете этот код? Мой выбор состоял в том, чтобы реализовать проверку маркера в качестве атрибута фильтра авторизации, полученного из AuthorizationFilterAttribute. Если вы украшаете контроллер атрибутом, его метод OnAuthorization выполняется перед каждым вызовом конечных точек контроллера. Вы помещаете вышеуказанный код в метод OnAuthorization и сохраняете принципала, возвращаемого проверкой маркера на HttpContext.Current.User, который также доступен на любой конечной точке вашего API. http://blogs.quovantis.com/json-web-token-jwt-with-web-api/ - хороший образец этой реализации.
Ответ 4
В любом контроллере net core 2, прошедшем авторизацию по схеме JwtBearerDefaults, вы можете использовать:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public ActionResult Index()
{
var user = User.FindFirst("Name").Value;
//or if u want the list of claims
var claims = User.Claims;
return View();
}