por basada autenticacion authentication rest

authentication - basada - autenticacion por token web api



REST y variantes de autenticación (3)

Actualmente estoy trabajando en una biblioteca REST para .net, y me gustaría escuchar algunas opiniones sobre un punto abierto que tengo: REST y autenticación.

Aquí hay un ejemplo de una interfaz RESTful utilizada con la biblioteca:

[RestRoot("/user")] public interface IUserInterface { [RestPut("/")] void Add(User user); [RestGet("/")] int[] List(); [RestGet("/get/{id}")] User Get(int id); [RestDelete("/delete/{id}")] void Delete(int id); }

El código del servidor entonces simplemente implementa la interfaz y los clientes pueden obtener la misma interfaz a través de una fábrica. O si el cliente no está usando la biblioteca, una solicitud HTTP estándar también funciona.

Sé que existen las principales formas de utilizar HTTP Basic Auth o enviar un token a las solicitudes que requieren usuarios autenticados.

El primer método (HTTP Basic Auth) tiene los siguientes problemas (en parte, navegador web específico):

  • La contraseña se transmite con cada solicitud, incluso con SSL esto tiene algún tipo de "mal presentimiento".
  • Dado que la contraseña se transmite con un encabezado de solicitud, sería fácil para un atacante local mirar los encabezados transmitidos para obtener la contraseña.
  • La contraseña está disponible en la memoria de los navegadores.
  • No hay una forma estándar de expirar las "sesiones" del usuario.
  • Iniciar sesión con un navegador interrumpe el aspecto de una página.

Los problemas para el segundo método están más centrados en la implementación y el uso de la biblioteca:

  • Cada URI de solicitud que necesita autenticación debe tener un parámetro para el token, que es muy repetitivo.
  • Hay mucho más código por escribir si cada implementación de método necesita verificar si un token es válido.
  • La interfaz se volverá menos específica, por ej. [RestGet("/get/{id}")] vs. [RestGet("/get/{id}/{token}")] .
  • Dónde colocar el token: al final del URI? después de la raíz? ¿en algún otro lugar?

Mi idea era pasar el token como parámetro a la URL como http:/server/user/get/1234?token=token_id .

Otra posibilidad sería enviar el parámetro como un encabezado HTTP, pero esto complicaría el uso con clientes HTTP simples, supongo.

El token se volvería a pasar al cliente como un encabezado HTTP personalizado ("X-Session-Id") en cada solicitud.

Esto podría ser completamente abstraído de la interfaz, y cualquier implementación que necesite autentificación podría simplemente preguntar a qué usuario pertenece el token (si se le dio).

¿Crees que esto violaría REST demasiado o tienes mejores ideas?


El resto de la autenticación que he visto trata las sesiones como un recurso REST para la creación, destrucción, etc. y luego la identificación de la sesión se pasa de un lado a otro. Los que he visto tienden a usar la cookie de sesión para esto, ya que es la única forma de protegerlo realmente. Si pasa la identificación de la sesión en la URL, no tiene ninguna forma de realmente autenticar que proviene del cliente correcto.

Sin embargo, la autenticación es un problema difícil con REST, ya que requiere que se guarde alguna forma de estado fuera de la URL que infringe los principios REST de la URL, ya que es todo lo que se necesita para representar el estado.


Estoy de acuerdo con workmad3, si necesita mantener la duración de la sesión, debe crear un recurso de sesión. Publicar en ese recurso con credenciales de usuario (autenticación básica o credenciales en el contenido del cuerpo) devolverá una identificación de sesión única. Eliminar en / session / {id} cerrará la sesión del usuario.

Si desea controlar el tiempo de caducidad de la sesión. Al crear una nueva sesión (publicar en el recurso de la sesión), el servidor configurará una cookie en la respuesta (usando el encabezado de conjunto de cookies estándar). La cookie contendrá el tiempo de caducidad. La cadena de cookies se debe cifrar en el servidor, por lo que solo el servidor puede abrir esa cookie. Cada solicitud consiguiente al servidor enviará la cookie de sesión en el encabezado de la cookie. (se hará automáticamente si su cliente es un navegador). El servidor necesita "renovar" la cookie para cada solicitud, es decir, crear una nueva cookie con un nuevo tiempo de caducidad (extender el tiempo de espera de la sesión). Recuerde borrar la cookie cuando el usuario llame a delete en el recurso de la sesión.

Si desea que su aplicación sea más segura, puede almacenar la IP del cliente en la misma cookie, de modo que cuando llegue una solicitud, el servidor puede validar que fue enviada desde el cliente "original". Pero recuerde que esta solución puede ser problemática cuando se trata de proxys, ya que el servidor podría "ver" todas las solicitudes como procedentes del mismo cliente.


Tiendo a creer que los detalles de autenticación pertenecen al encabezado, no al URI. Si confía en que se colocará un token en el URI, será necesario codificar cada URI de su aplicación para incluir el token. También afectaría negativamente el almacenamiento en caché. Los recursos con un token que cambia constantemente ya no podrán almacenarse en caché. La información relacionada con el recurso pertenece al URI, no a los datos relacionados con la aplicación, como las credenciales.

Parece que debe estar apuntando a navegadores web como cliente? De ser así, podría investigar utilizando la autenticación de acceso HTTP Digest o emitir a los clientes sus propios certificados SSL para identificarlos y autenticarlos de manera única. Además, no creo que las cookies de sesión sean necesariamente malas. Especialmente cuando tienes que lidiar con un navegador. Siempre que aisle el código de manejo de las cookies y haga que el resto de la aplicación no dependa de él, estaría bien. La clave es solo almacenar la identidad del usuario en la sesión, nada más. No abuse del estado de la sesión del servidor.

Si se dirige a clientes que no sean el navegador, existen varios enfoques que puede tomar. Tuve suerte al usar el mecanismo de Autenticación S3 de Amazon.

Todo esto es muy subjetivo, por supuesto. La pureza y seguir REST a la carta a veces puede ser poco práctico. Mientras minimices y aísles ese comportamiento, el núcleo de tu aplicación aún puede ser RESTful. Recomiendo los servicios web RESTful como una gran fuente de información y enfoques de REST.