Окончание токена OAuth в приложении MVC6 - программирование
Подтвердить что ты не робот

Окончание токена OAuth в приложении MVC6

Итак, у меня есть приложение MVC6, которое включает в себя сервер идентификации (с использованием ThinkTecture IdentityServer3) и приложение веб-служб MVC6.

В приложении веб-служб я использую этот код в Startup:

app.UseOAuthBearerAuthentication(options =>
{
    options.Authority = "http://localhost:6418/identity";
    options.AutomaticAuthentication = true;
    options.Audience = "http://localhost:6418/identity/resources";
});

Затем у меня есть контроллер с действием, имеющим атрибут Authorize.

У меня есть приложение JavaScript, которое проходит проверку подлинности на сервере идентификации, а затем использует предоставленный токен JWT для доступа к действию веб-служб.

Это работает, и я могу получить доступ только к действию с действительным токеном.

Проблема возникает, когда JWT истек. То, что я получаю, - это то, что кажется сложной страницей ошибок ASP.NET 500, которая возвращает информацию об исключении для следующего исключения:

System.IdentityModel.Tokens.SecurityTokenExpiredException IDX10223: Не удалось проверить срок службы. Срок действия маркера истек.

Я новичок в OAuth и защищаю веб-API в целом, поэтому я могу быть вне базы, но ошибка 500 не кажется мне подходящей для истекшего токена. Это определенно не подходит для клиента веб-сервиса.

Является ли это ожидаемым поведением, а если нет, есть ли что-то, что мне нужно сделать, чтобы получить более подходящий ответ?

4b9b3361

Ответ 1

Изменить: эта ошибка была исправлена ​​в ASP.NET Core RC2, и обходной путь, описанный в этом ответе, больше не нужен.


Примечание. Это обходное решение не будет работать в ASP.NET 5 RC1, из-за этой другой ошибки. Вы можете либо перейти на ночные сборки RC2, либо создать собственное промежуточное программное обеспечение, которое улавливает исключения, выданные промежуточным программным обеспечением JWT-носителя, и возвращает ответ 401:

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;
    }
});

К сожалению, в настоящее время по умолчанию используется промежуточное ПО-носитель JWT/OAuth2 (управляемое MSFT), но оно должно быть в конечном итоге исправлено. Вы можете увидеть этот билет GitHub для получения дополнительной информации: https://github.com/aspnet/Security/issues/411

К счастью, вы можете "легко" обойти это, используя уведомление AuthenticationFailed:

app.UseOAuthBearerAuthentication(options => {
    options.Notifications = new OAuthBearerAuthenticationNotifications {
        AuthenticationFailed = notification => {
            notification.HandleResponse();

            return Task.FromResult<object>(null);
        }
    };
});