Tengo que implementar una autenticación basada en token para un servicio web RESTful. Esta es la primera vez que estoy implementando funciones de seguridad en un software, y esto es lo que tengo en mente por ahora:
- El cliente primero se autentica a través de un formulario de inicio de sesión (en la aplicación cliente) con su correo electrónico y contraseña.
- Si la autenticación tiene éxito, el usuario obtendrá en una respuesta una clave privada (generada aleatoriamente) y un token (cadena: ¿generada aleatoriamente?). El servidor almacenará en la base de datos (¿o tal vez un caché?) Una tupla con los siguientes campos (correo electrónico, clave privada, hashedToken, caducidad del token), donde hashedToken es el valor del HMAC calculado sobre el token, con la clave privada .
- El cliente almacena la clave privada recibida y el token (en la memoria).
- Para cada solicitud futura, el cliente incluirá en un encabezado personalizado (es decir, authToken) el valor del HMAC calculado sobre el token, codificado con la clave privada y el correo electrónico del usuario (en otro encabezado) y reemplazará el token almacenado en memoria con el token recién generado.
- Cuando el servidor recibe la solicitud, comprueba si la tupla calcula la dirección de correo electrónico, comprueba si el token almacenado y el token recibido son iguales y si el token no ha caducado. Si está bien, el servidor actualiza la fecha de caducidad de la tupla y el campo hashedToken se establece en el valor de HMAC calculado sobre el token anterior, con la clave privada. el servidor procesa la solicitud (no se incluyen encabezados de autenticación adicionales ni información incluida en la respuesta)
Los pasos 1 y 2 utilizarán HTTPS. Otras solicitudes serán enviadas por HTTP, ya que se genera un nuevo token después de cada solicitud exitosa (oler el token sería inútil para un atacante, creo).
Me gustaría saber cuáles son los problemas con este protocolo de autenticación y cómo podría mejorarse.
Además, ¿este enfoque sería más rápido que simplemente incluir el correo electrónico y la contraseña en un encabezado en cada solicitud y usar HTTPS?