Como revogar o RefreshToken e invalidar o AccessToken ao mesmo tempo no Oauth2
Estou desenvolvendo o fluxo de autenticação de um aplicativo de página única (API AngularJS + .Net MVC Json Rest) usando Owin Oauth2 (os servidores de Autorização e Recursos são os mesmos).
Eu escolhi a rota do token do portador em vez da sessão tradicional de cookie + porque gostaria de permanecer apátrida e também porque a mesma API será usada por um aplicativo móvel em que o token tem menos problemas que o cookie.
Este é o fluxo simplificado:
O usuário envia nome de usuário / senha para o servidor (POST sobre Https na rota TokenProvider)Owin cria umAccessToken
com uma declaração que contém um GUID gerado (que representa algo como um ID da sessão) e algumas outras declarações.Owin cria umRefreshToken
.O servidor cria uma entrada noRefreshToken
tabela com os seguintes campos:GUID (PK) | RefreshToken | Ticket | DateIssued | DateExpire | DateEnd
O servidor fornece os doisAccessToken
e aRefreshToken
para o cliente.
O cliente armazena osAccessToken
eRefreshToken
no SessionStorage.
O cliente acessa a API com oAccessToken
.
Quando o AngularJS detecta que o AccessToken está próximo de expirar, ele armazena em buffer todas as solicitações e emite umgrant_type refresh_token request
;
servidor usa oRefreshToken
fornecido pelo cliente e:
DateExpire > GetTime() And DateEnd is Null
)Pega o ingresso de DbCria um AccessToken a partir do ticketAtualiza a entrada db com as novas datas, o novoRefreshToken
e o novo ticket (Observação: o GUID permanece o mesmo)Quando o cliente atinge o lado do servidor de logout, a leitura do GUID da reivindicação de identidade do usuário conectado é usada para invalidar a entrada na tabela (DateEnd = GetTime()
)
No lado do cliente, ambos os tokens são removidos doSessionStorage
.
Dessa forma, posso revogar oRefreshToken
negando quaisquer outros pedidos para obter uma novaAccessToken
.
O problema dessa abordagem é que, há uma janela de tempo em que a autorização é revogada (ou seja:RefreshToken
invalidado no DB), mas oAccessToken
ainda é válido (embora por um período de tempo limitado).
O que estou pensando em fazer é verificar a validade doAccessToken
em cada solicitação, obtendo o GUID das declarações de identidade do usuário e pressionando o db para verificar se o token de atualização desse GUID específico ainda é válido.
Embora seja bastante trivial fazer consultas executando O (1), o próprio ponto único de falha pode ter um impacto negativo na escalabilidade e no desempenho do sistema.
Você conhece outro método para mitigar esse problema e vê alguma falha na minha abordagem?