por example basada autenticacion java rest authentication httpclient

java - example - Las mejores prácticas para la gestión de token de autenticación



json web token java (10)

Estoy escribiendo un cliente REST en Java usando HttpCLient, la API REST a la que tengo acceso necesita un token de autenticación para cada acción REST. Este token es válido por 24 horas.

La forma en que estoy manejando esto ahora es llamar al getAuth() " getAuth() " cada vez que necesito hacer una llamada REST que parece una sobrecarga en el servidor de autenticación.

¿Cómo puedo almacenar convenientemente este token de autenticación y administrar su ciclo de vida? ¿Hay algunas mejores prácticas documentadas?

Pensé en la siguiente solución

public class MySession { String user; String pass; public MySession(String user, String pass) { this.user = user; this.pass = pass; } public getAuth() { //user user, pass to get auth token } }

y luego pase el objeto de las sesiones a cualquier clase que necesite el token. Si el token ha caducado, vuelva a llamar a este método


  1. El token de autenticación para cada solicitud es el enfoque correcto.
  2. En la primera autenticación exitosa (nombre de usuario y contraseña), genere un par de claves públicas privadas. Almacenar clave privada como Session Security Token (SST) y enviar clave pública como Public Security Client Key (PSCK) a cliente
  3. En todas las solicitudes que no sean de inicio de sesión (o autenticación), el cliente enviará el PSCK para proteger el robo del nombre de usuario y la contraseña, y el servidor puede verificar el vencimiento interno del PSCK a intervalos regulares, lo que ahorra tiempo de procesamiento.
  4. Si el sistema tiene problemas de rendimiento en el lado de la autenticación, configure el servidor de autenticación por separado con escalabilidad.
  5. No hay token o contraseña para guardar en caché, intercambiarse sin cifrar y enviar fuera de la zona de seguridad. No publicar utilizando parámetros de URL.

Deberías usar JsonWebToken (JWT en pocas palabras) para este tipo de cosas. JWT tiene soporte incorporado para establecer la fecha de vencimiento. Hay muchas bibliotecas para usar este método y puedes leer más here

Hay implementaciones de java de currenlty 4 y todas pueden verificar si el token sigue siendo válido (verificación exp)


El estándar de facto no es implementar su propia solución (regla básica en seguridad: ¡no implemente sus propias cosas! ), Pero use la solución estándar de facto, a saber, los tokens web de JSON .

Documentación en el sitio, pero la idea básica es que solo necesita almacenar un valor (la clave privada del servidor), y luego puede verificar cada reclamación, emitida originalmente por el servidor (que en su caso contendrá un tiempo de caducidad) .


Entonces, si estoy entendiendo correctamente, estás usando el mismo token para todas tus solicitudes (lo que significa que mientras tu aplicación esté funcionando y actualices los tokens, deberías estar bien. Literalmente tuve el mismo problema y esto es cómo lo resolví. Tengo una clase de singleton, que se inicializa en el inicio de la aplicación por una vez y actualiza el token cuando se invalida. Estoy usando C #, Asp.NET MVC5 y AutoFac para DI, pero estoy seguro Puedes hacer lo mismo con Java y Spring.

Actualización de la propiedad de un singleton con Thread Safety


Por brevedad, supongo que está llamando a un punto final que no puede cambiar. La forma en que debe implementar dependerá en gran medida de si el token está basado en la aplicación o en el usuario (un token para todos los usuarios en una instancia de aplicación compartida o un token por usuario).

Si es un token de autenticación para toda la aplicación:

  • Guárdelo en la memoria junto con una marca de tiempo de tiempo de vida (o, alternativamente, detecte el error del token caducado, solicite un token nuevo y vuelva a intentar la solicitud original), actualícelo si no existe / caducó
  • Si le preocupa volver a solicitar tokens de API después de reiniciar una aplicación, también guárdela en la base de datos y cárguela al inicio, si existe.

Si es un token por usuario:

  • Guárdelo en su sesión de usuario, es exactamente para lo que se usan las sesiones, si está seleccionando usuarios, entonces tendrán una sesión y la sobrecarga ya estará allí
  • Si no desea volver a solicitar un token cada vez que inicie sesión, almacene su token actual en la base de datos y cárguelo en su sesión cuando inicie sesión.

Puede crear un administrador y almacenar la cookie de autenticación durante el inicio de sesión en el hilo local como el código a continuación. Puede obtener la cookie de getAuth() siempre que el hilo viva.

public class Manager { private static final ThreadLocal<String> SECURITY_CONTEXT = new ThreadLocal<>(); public static void setAuth(String auth) { SECURITY_CONTEXT.set(auth); } public static String getAuth() { return SECURITY_CONTEXT.get(); } public static void clear(){ SECURITY_CONTEXT.remove(); } }


Si está preocupado por demasiados accesos a la base de datos, supongo que hay mucha actividad en la web.

No recomendaría usar Session en su caso, sino almacenar el token en una cookie en el cliente.

En un entorno de alto tráfico (que supongo que es el tuyo), el uso de Session puede consumir mucha memoria del servidor, y la escalabilidad también puede ser una preocupación, al tener que mantener las sesiones sincronizadas dentro de un clúster.

Como también mencionó @ Cássio Mazzochi Molin, puede usar un caché en memoria para almacenar cualquier dato y tokens específicos del usuario. Esto reducirá los accesos a la base de datos y también le permitirá escalar la aplicación más fácilmente, cuando surja la necesidad.


Supongo que está utilizando OAuth para la autorización. Si está utilizando JWT u otros tokens es irrelevante para esta situación.

Al realizar la autorización, se le emitirá un access_token con vencimiento y, según el tipo de concesión que solicite (credenciales del cliente, código de autorización, implícito, propietario del recurso), un refresh_token .

El cliente debe mantener el access_token y la caducidad. El refresh_token, si se emite, debe mantenerse en secreto (tenga cuidado de usar la concesión correcta para su caso de uso).

En las llamadas subsiguientes, su cliente no debe solicitar nuevos tokens en cada llamada, debe usar el access_token almacenado.

Una vez que la API comienza a devolver 401 Unauthorized , el access_token probablemente haya caducado. Su cliente debe intentar actualizar el access_token utilizando refresh_token si tiene uno.

Si no tiene refresh_token o la solicitud de actualización también falló, porque refresh_token ya no es válido, puede realizar un nuevo flujo de autorización.

Puede usar el tiempo de caducidad como una pista para saber cuándo obtener un nuevo access_token a través de la actualización o mediante un nuevo flujo de autorización completo. Esto evitará que el 401 Unauthorized . En cualquier caso, su cliente debe tener una política de retroceso cuando se recibe esta respuesta después de haber utilizado un access_token válido para algunas llamadas.


Te sugiero que uses el siguiente escenario:

1) Primero, llame a la api de rest de auth(username, password) para obtener el token de autenticación. Si las credenciales proporcionadas están bien, simplemente envíe la cookie de autenticación al cliente con el código de respuesta HTTP 200.

2) Entonces, puedes llamar a apis protegidos. Debe enviar una cookie de autenticación con su solicitud cada vez.

3) El filtro de servlet (o algo similar) verifica cada solicitud entrante y valida el token. Si el token es válido, la solicitud pasa al método de reposo, si no es así, debe generar una respuesta http 401/403.

Te sugiero que no escribas tu propia capa de autenticación. En lugar de instalar y utilizar uno existente. Te sugiero OpenAM . Es un excelente sistema de gestión de acceso de código abierto.

También le sugiero que no abra una sesión en el lado del servidor para fines de autenticación. Si tiene 10 clientes, el servidor debe administrar 10 sesiones. No es un gran problema. Pero si tiene 100 o 1000 o millones de clientes diferentes de los que necesita más memoria para almacenar sesiones en el servidor.


Use tokens web de json para intercambiar información entre dos clientes. El token solo estará activo durante el período de 24 horas, después de ese tiempo todas las llamadas resultantes en el encabezado serán rechazadas.