Как отозвать RefreshToken и аннулировать AccessToken одновременно в Oauth2
Я разрабатываю поток аутентификации одностраничного приложения (AngularJS + .Net MVC Json Rest API) с использованием Owin Oauth2 (серверы авторизации и ресурсов одинаковы).
Я выбрал маршрут Bearer Token вместо традиционного сеанса cookie +, потому что хотел бы остаться без состояния, а также потому, что тот же Api будет использоваться мобильным приложением, в котором токен имеет меньше проблем, чем cookie.
Это упрощенный поток:
Пользователь отправляет имя пользователя / пароль на сервер (POST через Https к маршруту TokenProvider)Овин создаетAccessToken
с заявкой, содержащей сгенерированный GUID (которая будет представлять собой что-то вроде идентификатора сеанса) и некоторыми другими заявками.Овин создаетRefreshToken
.Сервер создает запись вRefreshToken
таблица со следующими полями:GUID (PK) | RefreshToken | Ticket | DateIssued | DateExpire | DateEnd
Сервер дает какAccessToken
иRefreshToken
клиенту.
Клиент хранит какAccessToken
а такжеRefreshToken
в SessionStorage.
Клиент обращается к API с помощьюAccessToken
.
Когда AngularJS обнаруживает, что AccessToken близок к истечению, он буферизует все запросы и выдаетgrant_type refresh_token request
;
Сервер используетRefreshToken
предоставляется клиентом и:
DateExpire > GetTime() And DateEnd is Null
)Берет билет от DbСоздает AccessToken из билетаОбновляет запись в БД со свежими датами, новыеRefreshToken
и новый билет (Примечание: GUID остается прежним)Когда клиент достигает стороны сервера выхода из системы, GUID, считанный из утверждения личности зарегистрированного пользователя, используется для аннулирования записи в таблице (DateEnd = GetTime()
).
На стороне клиента оба токена удалены изSessionStorage
.
Таким образом, я могу отменитьRefreshToken
отклоняя любые другие запросы, чтобы получить свежийAccessToken
.
Проблема с этим подходом состоит в том, что существует окно времени, когда авторизация отменяется (то есть:RefreshToken
признан недействительным на БД) ноAccessToken
все еще действует (хотя в течение ограниченного периода времени).
Что я думаю сделать, это проверить достоверностьAccessToken
при каждом запросе беря GUID из заявлений об идентификации пользователя и нажимая db, чтобы проверить, все ли действителен токен обновления этого конкретного GUID.
Хотя выполнение запросов, выполняющих O (1), довольно тривиально, сама точка отказа может отрицательно повлиять на масштабируемость и производительность системы.
Знаете ли вы другой метод, чтобы смягчить эту проблему, и видите ли вы недостатки в моем подходе?