Tengo 3 proyectos de sitio web de la siguiente manera;
- identity.example.com (asp.netcore + IdentityServer4)
- api.example.com (asp.netcore webapi)
- www.example.com (asp.netcore + aurelia)
Puedo autenticar al usuario utilizando el agente de usuario de SPA usando un tipo de concesión implícito y almaceno el access_token en localStorage. Debido a que localStorage no es seguro, el acceso o el uso de larga duración o el uso de refresh_token no es seguro, por lo tanto, mis usuarios tendrán que iniciar sesión cada X minutos, lo que no es aceptable como usted estaría de acuerdo.
Mi objetivo es que los usuarios tengan la opción de "recordarme" y que mantengan las cosas tan seguras como aceptables (sé que no hay seguridad al 100% en este sentido)
Creo que tengo las siguientes opciones;
1. Proxy completo entre SPA y API / IdentityServer, todo lo almacenado como http_only cookie
- spa publica las credenciales en su propio backend (www.example.com/login)
- el backend del spa obtiene access_token y refresh_token de identity.example.com, almacena los tokens en la cookie http_only o en la sesión.
- el backend del spa actúa como un proxy entre la api y el spa y el spa realiza las llamadas a su propio backend, no a la api
- el backend del spa enruta todas las solicitudes de API a api.example.com usando el access_token almacenado en la cookie / sesión y devuelve el resultado al usuario_agente.
Ahora, este enfoque parece seguro, pero agrega un nivel de proxy que tendría un efecto negativo en el rendimiento, los tiempos de respuesta de las solicitudes, etc. Además, necesitaría escribir una envoltura / proxy para cada método de API en el backend del spa (el proxy ) Eso haría llamadas a los métodos de api reales, lo que no es tan bueno.
Pensé en el siguiente flujo para hacerlo seguro y no doloroso para el usuario al mismo tiempo;
2. Semi Proxy entre SPA e Identity Server (solo para actualizar tokens)
Resumen: el SPA tiene acceso a access_token. Sin embargo, para actualizar el token, el spa debe interactuar con su backend, que mantiene de forma segura el refresh_token en la sesión / cookie.
-
spa publica las credenciales en su propio backend (www.example.com/login) - spa obtiene un código de autorización del servidor de identidad (client_secret no es necesario para esto) y lo publica en su propio backend
- el backend del spa obtiene access_token y refresh_token de identity.example.com usando el código de autorización, almacena los tokens en la cookie http_only o en la sesión y también incluye access_token en el cuerpo de respuesta
- el spa almacena el access_token en su almacenamiento local, y lo usa para llamadas directamente a la api (api.example.com, sin proxy)
- cuando caduque el access_token, el usuario-agente (spa) le pide a su propio backend que actualice el access_token en nombre de sí mismo
- el backend del spa recupera el nuevo access_token y refresh_token del servidor de identidad. Actualiza los tokens en la sesión / cookie y devuelve access_token al user_agent (spa)
-
user_agent (spa) actualiza el access_token en su localStorage y lo usa para futuras llamadas a la api.
Ahora, las preguntas ... ¿Es el último flujo que he descrito seguro y aceptable según las normas? ¿Conoces un ejemplo de implementación de la misma? ¿O tienes otras sugerencias que debo seguir? Tal vez fallas de seguridad que debería considerar?