Autenticación basada en token utilizando el acceso y tokens de actualización

8

Estoy implementando un sistema de autenticación basado en token para una API REST usando un token de acceso de corta duración y un token de actualización de larga duración. Este es un resumen general de los puntos finales de API relevantes (HTTPS se aplica para todos los puntos finales):

Puntos finales:

POST /register/
POST /login/
POST /logout/
POST /password/change/

Implementación:

POST /register/ :

  • Solicitud: el cliente envía un nombre de usuario, correo electrónico y contraseña en JSON.
  • acciones del servidor:
    1. Valida la entrada, crea un usuario en la base de datos (almacena la identificación del usuario, el nombre de usuario, el correo electrónico y el hash de la contraseña).
    2. Crea un token de acceso de corta duración en formato JWT (contiene la identificación del usuario, la fecha de emisión y la fecha de caducidad).
    3. Crea un token de actualización de larga duración como una cadena UUID y lo almacena en la base de datos (almacena el identificador de usuario y el token de actualización).
  • Respuesta: el servidor devuelve el token de acceso y el token de actualización en JSON.

POST /login/ :

  • Solicitud: el cliente envía el nombre de usuario y la contraseña en JSON.
  • acciones del servidor:
    1. Valida la entrada, verifica si las credenciales son válidas al verificar la base de datos.
    2. Si las credenciales son válidas, crea un token de acceso de corta duración y un token de actualización de larga duración como se mencionó anteriormente.
  • Respuesta: Igual que /register/ , devuelve el token de acceso y el token de actualización en JSON.

POST /logout/ :

  • Solicitud: el cliente envía el token de actualización en el encabezado Authorization como token Bearer .
  • acciones del servidor:
    1. Valida el token de actualización al verificar la base de datos del token de actualización.
    2. Elimina el token de actualización de la base de datos.
      Nota: Esto deja el token de acceso válido, pero como será de corta duración (alrededor de 1 hora, creo que debería estar bien ).
  • Respuesta: devuelve si la solicitud de cierre de sesión se procesó correctamente en JSON.

POST /password/change/ :

  • Solicitud: el cliente envía el token de acceso en el encabezado Authorization como token Bearer , y también envía la contraseña antigua y la nueva en JSON a través de HTTPS.
  • acciones del servidor:
    1. Decodifica el token de acceso para recuperar al usuario y comprueba la contraseña anterior del usuario con la base de datos.
    2. Establece el hash de contraseña del usuario en la base de datos al hash de la nueva contraseña.
    3. Elimina todos los tokens de actualización asociados con el usuario en la base de datos del token de actualización para esencialmente cerrar sesión en las sesiones existentes (deja los tokens de acceso de corta duración válidos).
  • Respuesta: devuelve si la solicitud de cambio de contraseña se procesó correctamente en JSON.

Preguntas:

  1. ¿Es seguro este enfoque? Específicamente:
    • ¿Es seguro enviar el nombre de usuario y la contraseña a través de JSON si se realiza a través de HTTPS? ¿Cómo evitaría que los dominios no autorizados realicen llamadas a este punto final? Además, ¿cómo evitaría los inicios de sesión programáticos?
    • ¿Deben estar marcados los tokens de actualización antes de almacenarlos en la base de datos, o simplemente estoy siendo paranoico?
  2. Si el cliente fuera un navegador web, ¿cómo almacenaría de forma segura el token de actualización en el cliente?
    • Una idea que tengo para almacenar el token de actualización es: cuando el usuario inicia sesión, además de enviar el token de actualización al cliente, el servidor almacena el token en una cookie HttpOnly con un indicador secure . La autorización aún se realizará a través del encabezado Authorization , pero cuando el cliente se carga inicialmente, puede enviar una solicitud GET a un punto final que verifica si la cookie contiene un token de actualización válido y, si es así, lo devuelve al usuario en json. En otras palabras, la única vez que se usará realmente la cookie es devolver el token de actualización dentro de la cookie al cliente. ¿Es este enfoque seguro? Creo que evitará CSRF ya que no hay efectos secundarios al solicitar el token de actualización de la cookie, pero ¿hay alguna otra forma en que un atacante podría interceptar el token de actualización (asumiendo HTTPS)?
pregunta Kootling 30.06.2017 - 21:21

1 respuesta

2
  

¿Este enfoque es seguro? Específicamente:

     
  • ¿Es seguro enviar el nombre de usuario y la contraseña a través de JSON si se realiza a través de HTTPS?
  •   

Sí. Los encabezados, los parámetros de solicitud y el cuerpo de solicitud se cifran durante la comunicación.

Una vez en el lado del servidor, no registre el cuerpo de la solicitud :-)

  
  • ¿Cómo evitaría que dominios no autorizados realicen llamadas a este punto final?
  •   

No puedes. Básicamente, una vez que la API está en la WWW, se expone automáticamente a todo tipo de malicia. Lo mejor que puede hacer es estar preparado y estar al tanto de las amenazas. Al menos sobre los que te preocupan. Mire aquí .

Un posible enfoque del problema podría ser implementar (o contratar) un Administrador de API .

Los administradores de API locales pueden reducir la superficie de ataque porque todos los puntos finales detrás de la mañana no son necesariamente públicos.

Podría obtener el mismo resultado con algunos productos en la nube, pero son absurdamente costosos para la corriente principal.

De todos modos, los puntos finales de administración de API permanecerán expuestos a los ataques.

  
  • Además, ¿cómo evitaría los inicios de sesión programáticos?
  •   

Si por inicios de sesión programáticos te refieres a ataques por fuerza bruta, un umbral (número máximo de solicitudes permitidas por segundo) y una lista negra deberían ser suficientes para disuadir la insistencia del atacante. Para obtener más información, consulte aquí .

Muchos de los administradores de API proporcionan configuraciones listas para el límite de velocidad API y listas blancas .

Si está familiarizado con la Consola de API de Google, puede adivinar qué puede hacer un Administrador de API.

  
  • En caso de que los tokens de actualización estén marcados antes de guardarlos en el   base de datos, o estoy siendo paranoico?
  •   

Si el token de actualización es un UUID simple o cualquier otra cosa, no me gusta exponer este tipo de detalles de implementación. Así que te sugiero que lo hagas. Para mí, cuanto más opacos sean los detalles de implementación de la capa de seguridad, mejor.

Con respecto a la seguridad de JWT, eche un vistazo a aquí .

  
  • Si el cliente fuera un navegador web, ¿cómo almacenaría de forma segura el   token de actualización en el cliente?
  •   

Puede que estés interesado en JSON Web Token (JWT) - Storage on client side .

    
respondido por el Laiv 30.06.2017 - 23:11

Lea otras preguntas en las etiquetas