Пользовательская пожизненная проверка с помощью 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?

  • Можем ли мы заставить ODC не включать определенные пожизненные заявки в токен, такие как «nbf», поскольку они нам все равно не понадобятся?


person 42vogons    schedule 09.12.2015    source источник


Ответы (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;
    }
});
person Kévin Chalet    schedule 09.12.2015
comment
Спасибо, @Pinpoint. Не могли бы вы также сообщить мне, можем ли мы контролировать, какие пожизненные заявки включаются в токен, который генерирует OIDC? Например, можем ли мы удалить iat, nbf и т. д.? - person 42vogons; 10.12.2015
comment
У вас нет прямого доступа к этим непользовательским утверждениям, но есть лучшие способы контролировать время жизни токенов, выдаваемых сервером OIDC: самый простой — через параметры (путем обновления AccessTokenLifetime/IdentityTokenLifetime/RefreshTokenLifetime). Другой — через событие SerializeAccessToken, где вы можете обновить свойства IssuedUtc/ExpiresUtc, связанные с билетом аутентификации (через context.AuthenticationTicket.Properties). - person Kévin Chalet; 10.12.2015
comment
Для всех, кто читает эти комментарии, мы обнаружили, что перехват SecurityTokenInvalidLifetimeException в приведенном выше примере кода точно соответствует нашим потребностям. - person 42vogons; 10.12.2015
comment
Чтобы избежать ответа 500, когда срок действия токена доступа истек, перехват SecurityTokenInvalidLifetimeException будет работать. Но обработчик токена безопасности также выдает другие типы исключений (например, InvalidOperationException), когда токен доступа искажен или изменен. - person Kévin Chalet; 10.12.2015