Cómo manejar tokens de actualización

2

Estoy tratando de envolver mi cabeza alrededor de la autenticación basada en JWT (token web JSON) para asegurar los puntos finales de API utilizando tokens de acceso. Estoy protegiendo estos puntos finales al requerir que el usuario tenga un token de acceso válido para obtener dichos recursos.

Sin embargo, estoy teniendo problemas para entender el uso de tokens de actualización.

Tengo un punto final / auth / login que acepta POST peticiones:

class UserLogin(Resource):
    def post(self):
        data = parser.parse_args()
        current_user = User.find_by_username(data['username'])
        if not current_user:
            return {'message': 'Unsuccessful. You do not have an account'}

        if User.verify_hash(data['password'], current_user.password):
            access_token = create_access_token(current_user)
            refresh_token = create_refresh_token(current_user)
            return {
                'message': 'Login successful {}'.format(current_user.username),
                'roles': 'Role: {}'.format(current_user.role),
                'access token': access_token,
                'refresh token': refresh_token
            }
        else:
            return {'message': 'Something went wrong'}

El punto final esencialmente verifica las credenciales entrantes para asegurar que el usuario exista en mi almacén de usuarios. Si lo hacen, devolveré un token de acceso y actualización. De lo contrario, un mensaje de error para ser manejado por el lado del cliente.

Ahora, suponga que el usuario ha iniciado sesión e intenta acceder a un recurso privado desde otro punto final asegurado al requerir un token de acceso. El cliente realizará una solicitud y el punto final protegido devolverá un mensaje de error que indica que no tiene un token de acceso. El cliente intentará generar un nuevo token de acceso utilizando el token de actualización obtenido al iniciar sesión:

class TokenRefresh(Resource):
    @jwt_refresh_token_required
    def post(self):
        current_user = get_jwt_identity()
        access_token = create_access_token(identity=current_user)
        return {'access token': access_token}

Al golpear el recurso anterior se generará un nuevo token de acceso con un tiempo de caducidad definido. Este es mi flujo actual.

Mi pregunta es, ¿cómo debo almacenar los tokens de actualización para garantizar que el usuario autenticado acceda a ellos? ¿Debo tener alguna lógica adicional en mis solicitudes de inicio de sesión que almacene el token de actualización generado para ese usuario específico?

Si es así, ¿debería generar un nuevo token de actualización y sobrescribir el token de actualización adjunto al usuario cada vez que el cliente intente actualizar su token de acceso?

Actualmente, siento que mi proceso puede verse comprometido si un atacante logra obtener el token de actualización.

    
pregunta Sam 30.09.2018 - 13:47
fuente

2 respuestas

1

El punto de tener tokens de acceso es que se pueden usar sin verificar la invalidación. Puede tener 10000 servidores frontend a los que los usuarios pueden acceder con el token sin tener que preguntar alguna vez a alguna base de datos si no es válida. Pero después de algún tiempo, el token caduca. El usuario necesita un nuevo token de acceso, envía su token de actualización y este token de actualización se verifica en alguna base de datos. Nunca es necesario verificar los tokens de acceso caducados o tener un estado, pero limitar el abuso a la vida útil del token.

Si no tiene el requisito de aceptar los tokens sin verificar el vencimiento en una base de datos, no necesita los dos tokens diferentes. Solo puede usar el token de actualización para cada acceso.

El flujo de trabajo de ejemplo sería:

  1. El usuario inicia sesión, obtiene acceso y actualiza el token. Acceda a la vida útil del token 15min, actualice el token 5 días.

  2. El usuario accede al servicio utilizando el token de acceso. Servicio solo cheques de firma y vida útil. Sin conexión a la base de datos.

  3. El usuario cierra la sesión, el token de actualización está marcado como caducado en la base de datos
  4. El usuario accede al servicio utilizando el token de acceso, esto todavía funciona
  5. pase 15min. El token de acceso caduca, el usuario solicita un nuevo token de acceso utilizando el token de actualización aún durante su vida útil. El servicio comprueba la base de datos y encuentra que el token ha caducado. El usuario no puede obtener un nuevo token de acceso.

Todo el sistema es un compromiso entre el tiempo que se tarda en invalidar las sesiones y la cantidad de conexiones a una fuente de datos compartida / sincronizada requerida.

Puede reemplazar el token de actualización en cada actualización, pero recuerde que debe almacenar todos los tokens de actualización caducados hasta que finalice su vida útil .

Desde una perspectiva de seguridad, tiene sentido crear un nuevo token, pero es una compensación entre la seguridad y la cantidad de datos en su base de datos.

En el peor de los casos (no hay vida para los tokens de actualización, nunca haga eso), ahora necesita almacenar un token cada pocos minutos en la base de datos para cada usuario en lugar de un token para cada usuario y usted Nunca podrás eliminarlos nuevamente.

    
respondido por el Josef 18.10.2018 - 13:25
fuente
0

Los tokens de actualización son una de esas tecnologías en las que la práctica y la teoría no coinciden, en mi experiencia. En teoría, realiza una solicitud de inicio de sesión y recupera un token de acceso (con una vida útil corta) y un token de actualización (que tiene un largo período de caducidad, no caducidad, y se puede utilizar para obtener un nuevo token de acceso en cualquier momento) ). Si el cliente intenta enviar un token de acceso caducado y recibe un rechazo del servidor, puede enviar el token de actualización, obtener un token de acceso nuevo y luego continuar.

En este caso, es muy claro que el token de actualización es realmente poderoso y debe almacenarse con cuidado (por ejemplo, en el almacenamiento de credenciales en un dispositivo móvil, en lugar de una cookie del navegador, o en una tienda del lado del servidor cuidadosamente asegurada) . Sin embargo, las especificaciones sí permiten que el servidor de autenticación invalide un token de actualización.

En la práctica, por lo tanto, no es infrecuente que se emita un token de actualización al iniciar sesión y se invalide al cerrar sesión o después de un período de inactividad. En este caso, puede formar parte de los datos de la sesión en el servidor y, por lo tanto, vincularse automáticamente con el usuario actual. Cualquier otro usuario solo podría usar el token de actualización desde la sesión autenticada, lo que significa que cualquier lógica que lo vincule a un usuario específico también fallará.

Desde el fragmento de código anterior, esto es prácticamente lo que tiene: el token de actualización se genera en cada inicio de sesión, en lugar de recuperarse del almacenamiento después de generarse en la creación de la cuenta, por ejemplo. La única parte que falta es cómo se consulta el token de actualización: se implica que el token de actualización se considera suficiente para obtener un token de acceso, en lugar de la combinación de una sesión autenticada y un token de actualización. Esto es, como sospechas, inseguro.

El token de actualización proporciona autorización para obtener un nuevo token de acceso, pero no autentica que la persona que solicita el token de acceso sea la que debe tener acceso. Debe proporcionar el paso de autenticación antes de aceptar la autorización y asegurarse de que se use cada vez que se use el token de actualización; una sesión abierta puede ser suficiente.

Puede elegir reemplazar el token de actualización en cada token de acceso nuevo. Esto tiene el beneficio adicional de romperse bastante obviamente si varios usuarios intentan usar el token de actualización (el segundo falla), por lo tanto, limita el uso simultáneo. Sin embargo, evite emitir nuevos tokens de actualización sin que caduque el anterior, ya que esto aumenta el potencial de compromiso de token. Es probable que tenga un beneficio limitado en el caso de que el token de actualización caduque con la sesión (suponiendo que la duración de la sesión sea corta), pero puede ayudar con sesiones más largas (por ejemplo, funciones "Recordarme").

    
respondido por el Matthew 18.10.2018 - 11:31
fuente

Lea otras preguntas en las etiquetas