Пользовательская проверка срока службы с помощью AspNet.Security.OpenIdConnect.Server (ASP.NET vNext)
Я использую Visual Studio 2015 Enterprise Update 1 и ASP.NET vNext rc1-update1 для выпуска и использования токенов JWT, как описано здесь.
В нашей реализации мы хотим контролировать время жизни токена.
Мы испробовали несколько подходов, каждый из которых имел нежелательные побочные эффекты. Например, в одной из попыток мы приняли событие TokenValidationParameters.TokenValidationParameters.LifetimeValidator в методе Configure:
app.UseJwtBearerAuthentication
(
options =>
{
options.TokenValidationParameters = new TokenValidationParameters()
{
LifetimeValidator = (DateTime? notBefore, DateTime? expires, SecurityToken securityToken, TokenValidationParameters validationParameters) =>
{
// Pretend to do custom validation
return false;
}
};
}
);
Это событие приводит к сбою проверки, как нам хотелось бы, но клиент получает ошибку 500, тогда как вместо этого мы хотим вернуть ошибку серии 400 и небольшую полезную нагрузку.
В другой попытке мы попробовали различные реализации TokenValidationParameters.Events, такие как проверка утверждений в событии ValidatedToken, но обнаружили, что мы не смогли помешать промежуточному программному обеспечению вызвать действие контроллера, за исключением выдачи исключения, которое вернуло нас к проблеме 500 ошибок.
Итак, мои вопросы:
Каковы наилучшие практики для принятия пожизненной проверки с помощью OIDC?
Можем ли мы заставить OIDC не включать в токен некоторые претензии на весь срок службы, такие как "nbf", поскольку они нам все равно не понадобятся?
1 ответ
Изменить: эта ошибка была исправлена в ASP.NET Core RC2. Обходной путь, описанный в этом ответе, больше не нужен.
Это известная ошибка К сожалению, обходной путь, который вы можете использовать в бета8, больше не работает в RC1.
Единственный вариант - написать промежуточное программное обеспечение, перехватывающее исключение, чтобы сервер не возвращал ответ 500. Конечно, это некрасиво и потенциально может скрывать важные исключения, но это единственный известный обходной путь, который работает с RC1.
Вот пример (не забудьте зарегистрировать его до промежуточного программного обеспечения канала-носителя JWT):
app.Use(next => async context => {
try {
await next(context);
}
catch {
// If the headers have already been sent, you can't replace the status code.
// In this case, throw an exception to close the connection.
if (context.Response.HasStarted) {
throw;
}
context.Response.StatusCode = 401;
}
});