¿Cómo realizar la autenticación sin estado (sin sesión) y sin cookies?

107

Bob usa una aplicación web para lograr algo. Y:

  • Su navegador está a dieta, por lo que no admite cookies .
  • La aplicación web es muy popular, trata con muchos usuarios en un momento dado, tiene que escalar bien. Siempre que mantener la sesión imponga un límite al número de conexiones simultáneas y, por supuesto, traerá una penalización de rendimiento no despreciable , nos gustaría tener un sistema sin sesión :)

Algunas notas importantes:

  • tenemos seguridad en el transporte ( HTTPS y sus mejores amigos);
  • detrás de las cortinas, la aplicación web delega muchas operaciones a servicios externos , en nombre del usuario actual (esos sistemas reconocen a Bob como uno de sus usuarios); esto significa que tenemos que enviarles las credenciales de Bob .

Ahora, ¿cómo autenticamos a Bob (en todas y cada una de las solicitudes)? ¿Cuál sería una forma razonable de implementar tal cosa?

  • jugar al tenis con las credenciales a través de campos ocultos de formulario HTML ... la pelota contiene las credenciales ( nombre de usuario y contraseña ) y las dos raquetas son el navegador y la aplicación web respectivamente. En otras palabras, podemos transportar datos de un lado a otro a través de campos de formulario en lugar de mediante cookies. En cada solicitud web, el navegador publica las credenciales. Sin embargo, en el caso de una aplicación de una sola página , esto puede parecer como jugar al squash contra una pared de goma, en lugar de jugar al tenis , ya que el formulario web que contiene las credenciales podría mantenerse activo durante toda la vida útil de la página web. (y el servidor se configurará para no devolver las credenciales).
  • almacenar el nombre de usuario y la contraseña en el contexto de la página - variables de JavaScript, etc. Se requiere una sola página aquí, en mi humilde opinión.
  • autenticación basada en token cifrada. En este caso, la acción de inicio de sesión daría como resultado la generación de un token de seguridad cifrado (nombre de usuario + contraseña + algo más). Este token se devolverá al cliente y las próximas solicitudes irán acompañadas del token. ¿Esto tiene sentido? Ya tenemos HTTPS ...
  • otros...
  • último recurso: no haga esto, almacene las credenciales en la sesión. La sesión es buena. Con o sin cookies.

¿Le viene a la mente alguna inquietud de seguridad / web con respecto a alguna de las ideas descritas anteriormente? Por ejemplo,

  • tiempo de espera : podemos mantener una marca de tiempo , junto con las credenciales (marca de tiempo = la hora en que Bob ingresó sus credenciales). Por ejemplo, cuando NOW - marca de tiempo> umbral , podríamos denegar la solicitud.
  • Protección de secuencias de comandos entre sitios : no debería ser diferente de ninguna manera, ¿verdad?

Muchas gracias por tomarse el tiempo de leer esto :)

turdus-merula
fuente
1
Puede agregar un token a cada URL. ASP.NET tiene un modo (heredado) para hacer eso. Esto prueba que puede funcionar.
usr
1
¿Donde está todo el mundo? :)
turdus-merula
2
Creo que tienes una idea bastante clara de las opciones disponibles. Confía en tu razonamiento y decide tú mismo.
usr
¿Es un complemento como Silverlight of Flash una opción?
Giu
@usr no está seguro de si es una buena idea, ya que si un pirata informático llega a los registros de su servidor web puede robar su token e iniciar sesión en su sistema.
GibboK

Respuestas:

74

Ah, me encantan estas preguntas: mantener una sesión sin sesión.

He visto varias formas de hacer esto durante mis períodos durante las evaluaciones de aplicaciones. Una de las formas populares es la forma de jugar al tenis que mencionaste: enviar el nombre de usuario y la contraseña en cada solicitud para autenticar al usuario. Esto, en mi opinión, no es seguro, especialmente si la aplicación no tiene una sola página. Tampoco es escalable, especialmente si desea agregar autorización a su aplicación además de la autenticación en el futuro (aunque supongo que también podría crear algo basado en inicios de sesión)

Un mecanismo popular, aunque no completamente sin estado (asumiendo que tiene ejecución de JavaScript) es incrustar la cookie de sesión en JavaScript. El tipo de seguridad que hay en mí está gritando ante esto, pero en realidad podría funcionar: cada solicitud tiene unX-Authentication-Tokenencabezado o algo así, y lo asigna a una base de datos, almacenamiento de archivos en la memoria, etc.en el backend para validar al usuario. Este token puede tener un tiempo de espera del tiempo que especificó, y si se agota, el usuario debe iniciar sesión nuevamente. Es bastante escalable: si lo almacena en una base de datos, se ejecuta su única instrucción SQL y con los índices correctos, debería llevar muy poco tiempo ejecutarlo, incluso con varios usuarios simultáneos. Sin embargo, las pruebas de carga aquí definitivamente ayudarían. Si leo la pregunta correctamente, este sería su mecanismo de token cifrado, aunque le sugiero encarecidamente que use un token criptográficamente aleatorio de, digamos, 32 caracteres, en lugar de usar una combinación de nombre de usuario + contraseña + cualquier otra cosa, de esta manera, permanece impredecible, pero aún puede asociarlo con el ID de usuario o algo por el estilo.

Lo que sea que termine usando, asegúrese de que se lo envíe de manera segura. HTTPS lo protege a través del cable, pero no lo protege si filtra el token de sesión a través de la URL (o peor aún, las credenciales a través de la URL). Recomendaría usar un encabezado, o si eso no es factible, enviar el token a través de una solicitud POST cada vez (esto significaría un campo de formulario oculto en el navegador del usuario). El último enfoque de usar una solicitud POST debe usar defensas CSRF, solo en caso de que, aunque sospecho que usar el token en sí podría ser una especie de defensa CSRF.

Por último, pero no menos importante, asegúrese de tener algún mecanismo en el backend para purgar los tokens caducados. Esta ha sido la pesadilla de muchas aplicaciones en el pasado: una base de datos de tokens de autenticación en rápido crecimiento que nunca parece desaparecer. Si necesita admitir inicios de sesión de varios usuarios, asegúrese de limitar el número o de tener un límite de tiempo más corto para cada token. Como dije antes, las pruebas de carga pueden ser la respuesta a esto.

Hay otras preocupaciones de seguridad en las que puedo pensar, pero son demasiado amplias para abordarlas en esta etapa; si tiene en cuenta todos los casos de uso (y abuso), probablemente debería poder hacer una implementación bastante buena de este sistema.

Karthik Rangarajan
fuente
¿No puedes hacer lo que hace el marco de juego y enviar una cookie firmada al usuario? Entonces, ¿esa cookie se ha enviado de vuelta al servidor para cada solicitud posterior?
J será
8
> Su navegador está a dieta, por lo que no admite cookies.
Karthik Rangarajan
4
¿ Alguna de estas sugerencias es realmente apátrida / sin sesión ? De sus cinco párrafos principales (a partir de la edición 2013-12-19 de la publicación): el n . ° 1 es introductorio, el n . ° 2 propone sesiones extra-kludgy Web2.0 ™ con sabor, el n . ° 3 son solo advertencias, el n . ° 4 analiza las implicaciones de statefulness , y el n. ° 5 es un final vago ... ¡Es tangencialmente informativo en el mejor de los casos!
JamesTheAwesomeDude
1

Acerca de la opción de inicio de sesión: creo que, por lo general, también desea apoyar sesiones para invitados.

Por lo tanto, si desea forzar el inicio de sesión, la opción de token cifrado podría ser buena. También podría ser bueno para la sesión de invitados de alguna manera. En otra dirección, combinaría entre agregar el token a la URL y la opción de tenis.

Tenga en cuenta que enviar credenciales solo en la URL puede ser peligroso. Por ejemplo, puede filtrar el token a través del encabezado de referencia HTTP o incluso por alguien que simplemente inspecciona su tráfico o mira su computadora.

Otra cosa, incluso si pudiera usar cookies, le recomendaría que agregue un token aleatorio o un verificador aleatorio, para protegerse de los ataques de falsificación de solicitudes entre sitios (CSRF).

Gari BN
fuente
3
El estado de una sesión se almacena en el servidor. La pregunta pide autenticación sin estado.
Kwebble