Cómo revocar RefreshToken e invalidar AccessToken al mismo tiempo en Oauth2
Estoy desarrollando el flujo de autenticación de una aplicación de una sola página (AngularJS + .Net MVC Json Rest API) usando Owin Oauth2 (los servidores de Autorización y Recursos son los mismos).
Elegí la ruta del token de portador en lugar de la sesión tradicional de cookie + porque me gustaría permanecer apátrida y también porque la misma Api será utilizada por una aplicación móvil donde el token tiene menos problemas que la cookie.
Este es el flujo simplificado:
El usuario envía el nombre de usuario / contraseña al servidor (POST sobre Https a la ruta TokenProvider)Owin crea unAccessToken
con un reclamo que contiene un GUID generado (que representará algo así como un Id. de sesión) y algunos otros reclamos.Owin crea unRefreshToken
.El servidor crea una entrada en elRefreshToken
tabla con los siguientes campos:GUID (PK) | RefreshToken | Ticket | DateIssued | DateExpire | DateEnd
El servidor le da a ambosAccessToken
y elRefreshToken
al cliente.
El cliente almacena tanto elAccessToken
yRefreshToken
en el SessionStorage.
El cliente accede a la API con elAccessToken
.
Cuando AngularJS detecta que AccessToken está a punto de caducar, almacena todas las solicitudes y emite ungrant_type refresh_token request
;
el servidor usa elRefreshToken
proporcionado por el cliente y:
DateExpire > GetTime() And DateEnd is Null
)Toma el boleto de DbCrea un AccessToken desde el ticketActualiza la entrada de db con las nuevas fechas, la nuevaRefreshToken
y el nuevo Ticket (Nota: el GUID sigue siendo el mismo)Cuando el cliente llega al lado del servidor de cierre de sesión, el GUID leído del reclamo de identidad del usuario registrado se usa para invalidar la entrada en la tabla (DateEnd = GetTime()
)
Del lado del cliente, ambos tokens se eliminan delSessionStorage
.
De esta manera, puedo revocar elRefreshToken
negar cualquier otra solicitud para obtener una nuevaAccessToken
.
El problema con este enfoque es que hay una ventana de tiempo cuando se revoca la autorización (es decir:RefreshToken
invalidado en DB) pero elAccessToken
sigue siendo válido (aunque por un período de tiempo limitado).
Lo que pienso hacer es verificar la validez deAccessToken
en cada solicitud, tomar el GUID de los reclamos de identidad del usuario y presionar la base de datos para verificar si el token de actualización de ese GUID específico aún es válido.
Aunque es bastante trivial realizar consultas que ejecutan O (1), el único punto de falla en sí mismo puede tener un impacto negativo en la escalabilidad y el rendimiento del sistema.
¿Conoces otro método para mitigar este problema y ves algún defecto en mi enfoque?