invocar - jwt json web token java example
Asegurar el servicio web REST usando token(Java) (2)
El enfoque se ve bien. No muy seguro Permítanme resaltar algunos de los ataques posibles con la solicitud.
Ataque Man-In-the-middle en una solicitud POST, el usuario puede alterar la solicitud y el servidor no tiene forma de garantizar que los datos no se alteren.
Ataque de repetición: en esto, el atacante no altera la solicitud. El atacante toca la solicitud y la envía al servidor varias veces en una breve duración, aunque es una solicitud válida, el servidor procesa la solicitud varias veces, lo cual no es necesario. Lea acerca de Nonce.
En el primer paso, el usuario envía sus credenciales, es decir, nombre de usuario y contraseña al servicio de inicio de sesión, y si tiene una aplicación basada en la web que también usa la misma contraseña, podría ser peligroso. Si en caso de que la contraseña se vea comprometida, la API y todo lo que esté en la Web esté expuesto, utilice un PIN diferente para acceder a la API. Además, asegúrese de que el token descifrado según lo especificado por usted, caduque después de un tiempo determinado.
Asegúrese de que el servicio (servidor de aplicaciones) tomcat. jboss nunca devuelve una página de servidor en caso de error interno, esto le da al atacante información adicional del servidor donde se implementa la aplicación.
- MODIFICADO BASADO EN SEGUNDO CORREO -
Sí, es correcto si usa SSL mutuo, pero en caso de que sea un acceso de una sola dirección, no tiene los certificados del cliente. Sería bueno si solo aseguraras todo en la solicitud, al igual que firmó (firma) SOAP, uno de los mecanismos fuertes de transferencia de datos. Pero el ataque por repetición es una posibilidad con HTTPS, simplemente maneja eso. El uso de Rest tokens encryption es bueno. ¿Y por qué no pedirle al cliente que descifre el token con la contraseña y devolver el resultado del descifrado con esto, puede validar el resultado, si está presente en su base de datos? ¿Este enfoque el usuario no envía la contraseña a través del cable incluso si es HTTPS?
Esta pregunta está relacionada de alguna manera con la pregunta a continuación vinculada. Sin embargo, necesito un poco más de claridad sobre algunos aspectos y algo de información adicional. Consulte: implementación de símbolo de autenticación de servicio web REST
Fondo:
- Necesito implementar seguridad para un servicio web REST usando token
- El servicio web está diseñado para ser utilizado con el cliente Java. Por lo tanto, la autenticación de formularios y las ventanas emergentes para las credenciales no son útiles.
- Soy nuevo en seguridad y encriptación REST
Esto es lo que he entendido hasta ahora:
Para primera solicitud:
- El usuario establece la conexión https (o el contenedor garantiza https usando 301)
- Usuario POSTs nombre de usuario y contraseña para iniciar sesión servicio
- Si las credenciales son válidas, nosotros:
- Generar un token temporal aleatorio
- Almacene el token aleatorio en el servidor asignándolo a un nombre de usuario real
- Encripte el token con una clave simétrica que solo el servidor conoce
- Hash el token cifrado
- Enviar el token cifrado y el hash al cliente
Para solicitudes posteriores:
- El cliente envía esta combinación de token y hash encriptada (usando el campo de nombre de usuario de basic?)
- Nos aseguramos de que el token cifrado no se manipule con el hash y luego lo descifremos
- Verificamos el token descifrado en la tabla de seguimiento de sesión para una entrada no caducada y obtenemos el nombre de usuario real (¿el vencimiento debe ser administrado por código?)
- Si se encuentra el nombre de usuario, en función de los roles permitidos, las operaciones permitidas se configuran
Más detalles:
- Como el cliente es un cliente de Java, la primera solicitud puede ser una POST que contenga las credenciales. Sin embargo, parece que puede exponer las credenciales antes de que se establezca https. Por lo tanto, ¿debería haber un GET ficticio en un recurso seguro para que https se establezca primero?
- Suponiendo que se requiere lo anterior, la segunda solicitud es una POST de inicio de sesión con credenciales. Esta solicitud se maneja manualmente (sin usar la autorización del contenedor). ¿Es esto correcto?
- La LoginAction anterior devuelve al usuario la combinación de token + hash encriptado
- El usuario lo configura en el encabezado que usa el mecanismo de autenticación BASIC (nombre de usuario del campo)
- Implementamos un JAASRealm para descifrar y validar el token, y encontrar los roles permitidos
- El resto del proceso de autorización está a cargo del contenedor con WebResourceCollection definido en web.xml
¿Es este el enfoque correcto?
¿Por qué no simplificarlo a lo siguiente?
Para primera solicitud:
- El usuario establece la conexión HTTPS al servidor (el servicio no escucha en otros puertos) y las credenciales POST para iniciar sesión en el servicio.
- El servidor responde con un encabezado HSTS para garantizar que toda la comunicación posterior sea HTTPS.
- Si las credenciales son válidas, nosotros:
- Genere un token temporal aleatorio que se genera de forma segura utilizando un CSPRNG . Haga esto lo suficientemente largo como para ser seguro (128 bit).
- Almacene el token aleatorio en el servidor asignándolo a un nombre de usuario real.
- Enviar el token aleatorio al cliente
Para solicitudes posteriores:
- El cliente envía el token en un encabezado HTTP personalizado a través de HTTPS.
- Token se encuentra en la base de datos y se asigna al nombre de usuario. Si el acceso encontrado se configura en función de los roles permitidos y las operaciones permitidas.
- Si no se encuentra, el usuario se considera no autenticado y tendrá que autenticarse nuevamente con el servicio de inicio de sesión para obtener un nuevo token.
En el lado del servidor, el token se almacenará con una fecha de caducidad. En cada acceso al servicio, esta fecha se actualizará para crear una caducidad móvil. Habrá un trabajo que se ejecutará cada pocos minutos para eliminar los tokens caducados y la consulta que verifica el token para una sesión válida solo comprobará los que no hayan expirado (para evitar sesiones permanentes si el trabajo programado falla por algún motivo) )
No es necesario codificar y encriptar los tokens dentro de la base de datos, ya que no agrega ningún valor real aparte de un toque de seguridad a través de la oscuridad . Podrías simplemente hacer hash. Esto evitaría que un atacante que logró llegar a la tabla de datos de la sesión secuestrara sesiones de usuario existentes.