Personalizar el encabezado HTTP de autorización

81

Necesito autenticar a un cliente cuando envía una solicitud a una API. El cliente tiene un token de API y estaba pensando en usar el Authorizationencabezado estándar para enviar el token al servidor.

Normalmente esta cabecera se utiliza para Basicy Digestautenticación. Pero no sé si puedo personalizar el valor de este encabezado y usar un esquema de autenticación personalizado, por ejemplo:

Authorization: Token 1af538baa9045a84c0e889f672baf83ff24

¿Recomendarías esto o no? ¿O hay un mejor enfoque para enviar el token?

Thomas Watson
fuente

Respuestas:

51

Puede crear sus propios esquemas de autenticación personalizados que utilicen el Authorization:encabezado; por ejemplo, así es como funciona OAuth .

Como regla general, si los servidores o proxies no comprenden los valores de los encabezados estándar, los dejarán tranquilos y los ignorarán. Está creando sus propias claves de encabezado que a menudo pueden producir resultados inesperados: muchos proxies eliminarán los encabezados con nombres que no reconocen.

Habiendo dicho eso, posiblemente sea una mejor idea usar cookies para transmitir el token, en lugar del Authorization:encabezado, por la simple razón de que las cookies fueron diseñadas explícitamente para llevar valores personalizados, mientras que la especificación para los métodos de autenticación incorporados de HTTP realmente no dice de cualquier forma, si quieres ver exactamente lo que dice, echa un vistazo aquí .

El otro punto sobre esto es que muchas bibliotecas de cliente HTTP tienen soporte integrado para autenticación Digest y Basic, pero pueden hacer la vida más difícil al intentar establecer un valor sin procesar en el campo de encabezado, mientras que todas brindan soporte fácil para cookies y permitir más o menos cualquier valor dentro de ellos.

DaveRandom
fuente
10
Es bueno escuchar que así es como funciona OAuth. No estoy seguro de que el uso de cookies facilite la implementación del cliente. A menos que su cliente sea un navegador, las reglas para trabajar con cookies (ruta, caducidad, etc.) son más complicadas de implementar en un cliente que simplemente recordar establecer un campo de encabezado. La mayoría de las bibliotecas cliente simplifican la configuración de los encabezados correctos.
Thomas Watson
2
@ThomasWatson, aunque no puedo estar en desacuerdo contigo sobre los puntos del alcance de las cookies, en realidad no debería importar aquí. El alcance de la autenticación HTTP (usando el Authorization:encabezado) es por dominio. Esto significa que si configura el dominio de la cookie en "este dominio" y la ruta en "/", tendrá un alcance idéntico al de la autenticación HTTP. Sin embargo, realmente depende de usted, pero como señala Julian Reschke, probablemente no debería definir un nuevo esquema de autenticación a menos que usted feel that you have something of generic use, algo que pueda usarse en otra aplicación.
DaveRandom
8

En el caso de la solicitud CROSS ORIGIN, lea esto:

Enfrenté esta situación y al principio elegí usar el Authorizationencabezado y luego lo eliminé después de enfrentar el siguiente problema.

AuthorizationEl encabezado se considera un encabezado personalizado. Por lo tanto, si se realiza una solicitud entre dominios con el Autorizationencabezado establecido, el navegador envía primero una solicitud de verificación previa . Una solicitud de verificación previa es una solicitud HTTP mediante el método OPTIONS, esta solicitud elimina todos los parámetros de la solicitud. Su servidor debe responder con Access-Control-Allow-HeadersEncabezado con el valor de su encabezado personalizado ( Authorizationencabezado).

Entonces, para cada solicitud que envía el cliente (navegador), el navegador envía una solicitud HTTP adicional (OPCIONES). Esto deterioró el rendimiento de mi API. Debe verificar si agregar esto degrada su rendimiento. Como solución temporal, estoy enviando tokens en parámetros http, que sé que no es la mejor manera de hacerlo, pero no puedo comprometer el rendimiento.

Abhishek Kumar
fuente
También estoy considerando enviar mi sessionID en http params. ¿Por qué dices que esta no es la mejor manera? Parece que tiene la ventaja de ser robusto contra los firewalls que eliminan los encabezados y también contra la degradación del rendimiento de origen cruzado. ¿Cuáles son sus desventajas?
thund
1
La desventaja es solo en el caso de la solicitud GET. Tuve que autenticar al usuario usando mis Authorization token(datos confidenciales) para mi aplicación. Por la misma razón que no deberíamos enviar datos confidenciales en GET, no deberíamos usar token de autorización en params. Según w3 w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3 "El protocolo HTTP NO DEBE utilizar formularios basados ​​en GET para el envío de datos confidenciales".
Abhishek Kumar
Puede almacenar el token en cookies si no le gustan los encabezados. (No confunda el token con la identificación de sesión). Tenga en cuenta que con PUT y DELETE enviará las OPCIONES de todos modos ... Tenga en cuenta que la mayoría de las veces utiliza un cliente REST del lado del servidor y un navegador no se considera un cliente REST muy bueno.
inf3rno
5

Esto está un poco anticuado, pero puede haber otros que busquen respuestas a la misma pregunta. Debería pensar qué espacios de protección tienen sentido para sus API. Por ejemplo, es posible que desee identificar y autenticar el acceso de la aplicación cliente a sus API para restringir su uso a aplicaciones cliente registradas conocidas. En este caso, puede utilizar elBasicesquema de autenticación con el identificador del cliente como el ID de usuario y el secreto compartido del cliente como la contraseña. No necesita esquemas de autenticación patentados, solo identifique claramente los que los clientes usarán para cada espacio de protección. Prefiero solo uno para cada espacio de protección, pero los estándares HTTP permiten tanto múltiples esquemas de autenticación en cada respuesta de encabezado WWW-Authenticate como múltiples encabezados WWW-Authenticate en cada respuesta; esto resultará confuso para los clientes de la API sobre qué opciones utilizar. Sea coherente y claro, entonces se utilizarán sus API.

Steve Dearborn
fuente
2

Recomendaría no utilizar la autenticación HTTP con nombres de esquemas personalizados. Sin embargo, si cree que tiene algo de uso genérico, puede definir un nuevo esquema. Consulte http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p7-auth-latest.html#rfc.section.2.3 para obtener más detalles.

Julian Reschke
fuente
El documento al que enlazar es un borrador de HTTP / 1.1. He estado tratando de buscar en el estándar final y no puedo encontrar nada al respecto. Tengo que registrar esquemas personalizados. ¿No podría ser esto simplemente que durante el proceso de redacción, quisieron encontrar y acordar los esquemas predeterminados?
Thomas Watson
Thomas, el documento al que hice referencia es la revisión de las RFC 2616/7 (que no tenían un registro de esquemas). Es un trabajo en progreso, pero está a punto de completarse.
Julian Reschke
1

Por favor, pruebe a continuación en cartero: -

En el ejemplo de la sección de encabezado funciona para mí.

Autorización: JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyIkX18iOnsic3RyaWN0TW9kZSI6dHJ1ZSwiZ2V0dGVycyI6e30sIndhc1BvcHVsYXRlZCI6ZmFsc2UsImFjdGl2ZVBhdGhzIjp7InBhdGhzIjp7InBhc3N3b3JkIjoiaW5pdCIsImVtYWlsIjoiaW5pdCIsIl9fdiI6ImluaXQiLCJfaWQiOiJpbml0In0sInN0YXRlcyI6eyJpZ25vcmUiOnt9LCJkZWZhdWx0Ijp7fSwiaW5pdCI6eyJfX3YiOnRydWUsInBhc3N3b3JkIjp0cnVlLCJlbWFpbCI6dHJ1ZSwiX2lkIjp0cnVlfSwibW9kaWZ5Ijp7fSwicmVxdWlyZSI6e319LCJzdGF0ZU5hbWVzIjpbInJlcXVpcmUiLCJtb2RpZnkiLCJpbml0IiwiZGVmYXVsdCIsImlnbm9yZSJdfSwiZW1pdHRlciI6eyJkb21haW4iOm51bGwsIl9ldmVudHMiOnt9LCJfZXZlbnRzQ291bnQiOjAsIl9tYXhMaXN0ZW5lcnMiOjB9fSwiaXNOZXciOmZhbHNlLCJfZG9jIjp7Il9fdiI6MCwicGFzc3dvcmQiOiIkMmEkMTAkdTAybWNnWHFjWVQvdE41MlkzZ2l3dVROd3ZMWW9ZTlFXejlUcThyaDIwR09IMlhHY3haZWUiLCJlbWFpbCI6Im1hZGFuLmRhbGUxQGdtYWlsLmNvbSIsIl9pZCI6IjU5MjEzYzYyYWM2ODZlMGMyNzI2MjgzMiJ9LCJfcHJlcyI6eyIkX19vcmlnaW5hbF9zYXZlIjpbbnVsbCxudWxsLG51bGxdLCIkX19vcmlnaW5hbF92YWxpZGF0ZSI6W251bGxdLCIkX19vcmlnaW5hbF9yZW1vdmUiOltudWxsXX0sIl9wb3N0cyI6eyIkX19vcmlnaW5hbF9zYXZlIjpbXSwiJF9fb3JpZ2luYWxfdmFsaWRhdGUiOltdLCIkX19vcmlnaW5hbF9yZW1vdmUiOltdfSwiaWF0IjoxNDk1MzUwNzA5LCJleHAiOjE0OTUzNjA3ODl9.BkyB0LjKB4FIsCtnM5FcpcBLvKed_j7rCCxZddwiYnU

Madan Dale
fuente
1
¿Realmente estás enviando contraseña / hash en JWT? Es un simple base64.
Zakhar
1
@Zakhar: es una práctica bastante común para los SPA encapsular toda la sesión del usuario dentro de JWT (ya que es un documento json completo), eliminando la necesidad de almacenamiento de sesiones en el lado del servidor.
cowbert
@cowbert: No estoy seguro de si es típico encapsular algo más que algún tipo de token de sesión en JWT (ver, por ejemplo, esta publicación ).
Alexander Abakumov
1
@AlexanderAbakumov ese artículo lleno de engaños, obtuvo algunos puntos, pero muchos de sus puntos no tienen sentido y algunos de ellos simplemente se oponen sin ninguna razón, puedo decir que le encantan las galletas y creo que necesita obtener algunos de Bakery y arregle su artículo, tuve muchas situaciones en las que usé cookies y desperdicié días de trabajo, JWT con localStorage me ahorró mucho dolor de cabeza y tiempo, son solo 2 horas de trabajo y bang, nunca más lo visite. Me pregunto si alguna vez desarrolló una aplicación móvil, probó navegadores con reglas de seguridad estrictamente restringidas, etc.
Al-Mothafar
@ Al-Mothafar: Te agradecería si expande en sus declaraciones como that article full of misleadings, a lot of his points does not make sense, etc., de alguna manera (es decir, es probable que sea algo más allá de un comentario aquí). ¿Quizás podrías escribir una respuesta o una publicación de blog? Sería muy interesante comparar argumentos.
Alexander Abakumov