Diseño de autenticación para API REST

11

Estoy trabajando en una API para un servicio REST que voy a producir y consumir. Pasé los últimos días tratando de descubrir cómo manejar la autenticación de manera agradable, y creo que finalmente se me ocurrió algo.

Se me ocurre esto en base a los siguientes hechos sobre la pila de aplicaciones:

  1. Cliente y servidor están en .NET4 (parte del cliente en el perfil del cliente)
  2. El servidor expone utilizando WCF REST
  3. Realmente no quiero guardar el nombre de usuario y la contraseña en la memoria de la aplicación

A partir del 3, quería usar una forma de autenticación de token, para que después de que el servidor verifique las credenciales, el cliente recupere un token para usarlo en el resto de la aplicación (esto me permitirá hacer otras cosas, como agota el tiempo de espera de los usuarios, pudiendo moverlos sin problemas entre las versiones web y de escritorio, etc. Después de descubrir cómo hacer que las llamadas se reproduzcan y sean resistentes a manipulaciones, se me ocurrió lo siguiente:

  1. Antes de que el cliente intente autenticarse, genera un par de claves Diffie-Hellman usando la ECDiffieHellmanCngclase.
  2. Envía la parte pública del par de claves a través del cable junto con el nombre de usuario y la contraseña (sobre HTTPS, por supuesto).
  3. El servidor autentica la combinación de nombre de usuario / contraseña, si tiene éxito, luego hace lo siguiente:
    1. Crea un token de sesión único
    2. Genera su propio par de claves DH y calcula el secreto compartido a partir de la clave pública proporcionada por el cliente
    3. Toma nota del token de sesión, el secreto compartido, el usuario y el tiempo de "última acción" (utilizado para una ventana de vencimiento continua) en su base de datos
    4. Devuelve el token de sesión, su clave DH pública y un mensaje de autenticación correcta
  4. El cliente toma la clave DH de la respuesta, calcula el secreto compartido y almacena el token y el secreto en la memoria.

A partir de este momento, la combinación de token / secreto de sesión funciona como la mayoría de las otras API REST, con la solicitud de huellas digitales y marca de tiempo, y luego se genera algún tipo de HMAC. Cada vez que un cliente realiza una acción contra el servidor, comprueba el par token / secreto, y permite la acción si es válida y no ha caducado, y actualiza el último registro de acción en la sesión.

No veo ningún defecto obvio, y probablemente esté sobre diseñado para esto, pero necesito aprender cómo hacerlo en algún momento. El HMAC evita los ataques de repetición, la negociación de DH ayuda a prevenir los ataques de MITM (no puedo pensar en un ataque viable desde la parte superior de mi cabeza entre HMAC / DH).

¿Algún agujero que alguien pueda hacer en esto?

Matt Sieker
fuente
No veo cómo la generación de las claves DH agrega seguridad en comparación con el simple uso de HTTPS en todas partes y el uso de cookies de sesión antiguas. Cuando se usa correctamente, HTTPS ya protege contra ataques de repetición y ataques de intermediarios.
Mentira Ryan

Respuestas:

5

En lugar de inventar el suyo, debería considerar leer la API de OpenAM y tomarla prestada.

http://forgerock.com/openam.html

OpenAM Wiki es particularmente útil

https://wikis.forgerock.org/confluence/display/openam/Home

No necesita usar sus componentes. Pero si usa su API, encontrará que su vida será más simple a largo plazo.

S.Lott
fuente
Hmm, no se ve mal, una cosa que me impide usarlo en este caso: somos una tienda .Net. Además, no hay mucho de usarlo con el lado del servidor WCF. El único enlace que no es spam que pude encontrar en Google al respecto apunta a usar WIF y WS-Federation.
Matt Sieker
1
@Matt Sieker: "No necesita usar sus componentes". Lea acerca de su API en lugar de inventar la suya.
S.Lott
Ah, creo que entiendo lo que quieres decir, los requisitos de devolución de llamada. Eso es interesante, podría investigarlo más, si no fuera por este proyecto, para los futuros. En lugar de hacer la autenticación como un fragmento atómico,
divídalo
Inicialmente desarrollamos el nuestro, pero luego nos mudamos a OpenAM hace varios años en IG Group. Muy contento con el producto de código abierto.
Robert Morschel,
2

Estoy 100% de acuerdo con @ S.Lott en que no quieres rodar el tuyo. Sugiero buscar otra alternativa: el Servicio de control de acceso (ACS) de Windows Azure. ACS cuesta dinero, pero es muy barato (10,000 transacciones por $ 0.01) y se maneja una buena cantidad de infraestructura. WIF se apalanca en el cliente.

Esta también es una solución basada en estándares / reclamos, que está de moda. Consulte este artículo sobre el uso de WCF y REST y ACS juntos .

Si está pensando en el futuro, este también es un mecanismo que puede crecer con usted, ya que tiene aplicaciones móviles fuera del firewall, socios, etc. Incluso si no desea utilizarlo, ya que agrega una dependencia fuera de su firewall, puede consultarlo para obtener ideas. Muy hábil.

¡Buena suerte! -Cuenta

codingoutloud
fuente