Esta es una situación bastante común en la que se encuentra, lo cual es bueno, ya que significa que la solución es bien conocida, discutida y probada.
- ¿Es suficiente una simple verificación de firma por App2? ¿O existe la necesidad de que envíe el token a la App1 para su verificación (hay una lista blanca de claves públicas para la App2)?
Correcto, una verificación de firma "simple" es todo lo que App2 necesita hacer para validar el token. Esto garantizará a.) El token fue dispensado por App1 y b.) Los reclamos (pares clave-valor) en el token no se han manipulado.
- Estoy considerando agregar una fecha de vencimiento por 30 minutos, ¿cómo debo manejar el token de actualización en el lado del cliente?
Esto se reduce más a las preferencias personales, pero no me gustan los tokens de actualización. Los tokens de actualización implican una fecha de vencimiento futura lejana (es decir, un par de días o una semana) y pueden ser muy dañinos si se los roban. Además, en mi experiencia, no hay una manera realmente buena de almacenar un secreto en el lado del cliente. Las cookies son inseguras y no creo que los DB del lado del cliente sean mucho mejores. Podría cifrarlo con la contraseña del usuario, pero eso requiere que el usuario vuelva a escribir la contraseña que anula el propósito del token de actualización, ¿no? Así que evitaría actualizar tokens si es posible.
- En lugar de los tokens de actualización de la generación, ¿es seguro decir que el token de acceso es de una sola vez y que App2 crea una sesión en el lado del servidor (usando los datos en el token)?
No veo ningún defecto en este plan, creo que es mucho más seguro que confiar en un token de actualización. La única advertencia aquí es garantizar que existe la capacidad de anular un token de acceso en App1. En otras palabras, si me autentico contra la App1, obtengo mi token y luego vengo a la App2, me autentico y obtengo mi ID de sesión, estoy feliz. Pero, un atacante podría robar mi token de la cookie de mi navegador. El atacante puede usar este token para obtener su propia sesión con mis credenciales en App2 siempre que el token aún no haya caducado. Por lo tanto, App1 y App2 tendrían que poder comunicarse en este escenario. App2 comprueba que App1 dice que el token aún no se ha utilizado. App2 lo usa, luego le dice a App1 que se usó, anule el token para que no pueda ser reutilizado en futuras solicitudes para generar otro ID de sesión.
Como puedes ver, eso se vuelve mucho más complicado. Pero, si no lo haces, realmente no estás usando tokens de una sola vez. Una alternativa sería que la caducidad del token sea MUY breve (es decir, cinco minutos o menos), tiempo suficiente para que el usuario sea redirigido y autenticado con App2 y obtenga su ID de sesión para la autenticación continua. Esta podría ser la ruta más simple, pero realmente depende del nivel de seguridad que desea alcanzar aquí.
De cualquier manera, el ID de sesión es una idea inteligente. Es probable que reduzca la carga en el servidor de App2, ya que no tendrá que volver a comprobar constantemente las firmas de token para cada solicitud.