Caracteres UTF-8 mutilados en el nombre de usuario de Autenticación básica HTTP


Estoy intentando construir un servicio web usando Ruby on Rails. Los usuarios se autentican a través de HTTP Basic Auth. Quiero permitir cualquier carácter UTF-8 válido en nombres de usuario y contraseñas.

El problema es que el navegador está alterando caracteres en las credenciales básicas de autenticación antes de enviarlos a mi servicio. Para las pruebas, estoy usando 'カタカナカタカナカタカナカタカナカタカナカタカナカタカナカタカナ' como mi nombre de usuario (ni idea de lo que significa - AFAIK es que algunos caracteres aleatorios nuestro QA tipo se acercó con - por favor, perdóname si es de alguna manera ofensivo).

Si tomo eso como una cadena y hago username.unpack ("h*") para convertirlo a hexadecimal, obtengo: '3e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a8' Eso parece correcto para 32 caracteres kanji (3 bytes/6 dígitos hexadecimales por).

Si hago lo mismo con el nombre de usuario que viene a través de HTTP Basic auth, conseguir: "bafbbaacbafbbaacbbaacbafbbaacbafbbaacbbaacbafbbaacbbaacbafbbaac". Obviamente es mucho más corto. Usando el plugin Firefox Live HTTP Headers, aquí está el encabezado real que se está enviando:

Authorization: Basic q7+ryqu/q8qrv6vKq7+ryqu/q8qrv6vKq7+ryqu/q8o6q7+ryqu/q8qrv6vKq7+ryqu/q8qrv6vKq7+ryqu/q8o=

Eso se parece a ese 'bafbba...'cadena, con los nibbles altos y bajos intercambiados (al menos cuando lo pego en Emacs, base 64 decodificar, a continuación, cambiar al modo hexl). Eso podría ser una representación UTF16 del nombre de usuario, pero no he conseguido nada para mostrarlo como nada más que galimatías.

Rails está configurando el encabezado content-type a UTF-8, por lo que el navegador debería enviar esa codificación. Obtengo los datos correctos para los envíos de formularios.

El problema ocurre tanto en Firefox 3.0.8 como en IE 7.

So... ¿hay alguna salsa mágica para conseguir que los navegadores web envíen caracteres UTF-8 a través de HTTP Basic Auth? ¿Estoy manejando las cosas mal en el extremo receptor? ¿HTTP Basic Auth simplemente no funciona con caracteres no ASCII?

Author: bignose, 2009-03-31

6 answers

Quiero permitir cualquier carácter UTF-8 válido en nombres de usuario y contraseñas.

Abandonen toda esperanza. La autenticación básica y Unicode no se mezclan.

No hay un estándar(*) sobre cómo codificar caracteres no ASCII en un token Básico de Autenticación username:password antes de base64ing. En consecuencia, cada navegador hace algo diferente:

  • Opera utiliza UTF-8;
  • IE utiliza la página de código predeterminada del sistema (que no tiene forma de saber, aparte de nunca es UTF-8), y silenciosamente mangles caracteres que no encajan en ella usando el Windows 'adivinar un carácter aleatorio que se parece un poco a la que quería o tal vez simplemente no' receta secreta;
  • Mozilla utiliza solo el byte inferior de los puntos de código de caracteres, lo que tiene el efecto de codificar a ISO-8859-1 y destrozar los caracteres no-8859-1 irremediablemente... excepto al hacer XMLHttpRequests, en cuyo caso utiliza UTF-8;
  • Safari y Chrome codifican según ISO-8859-1, y no se puede enviar el encabezado de autorización cuando se utiliza un carácter distinto de 8859-1.

*: algunas personas interpretan el estándar para decir que:

  • debe ser siempre ISO-8859-1, debido a que es la codificación predeterminada para incluir caracteres raw de 8 bits directamente incluidos en los encabezados;
  • debe ser codificado usando reglas RFC2047, de alguna manera.

Pero ninguna de estas propuestas está en el tema para su inclusión en un token de autenticación codificado en base64, y el RFC2047 la referencia en la especificación HTTP realmente no funciona en absoluto, ya que todos los lugares en los que podría usarse están explícitamente prohibidos por las reglas del 'contexto átomo' de RFC2047, incluso si las cabeceras HTTP respetaban las reglas y extensiones de la familia RFC822, lo cual no lo hacen.

En resumen: ugh. Hay poca o ninguna esperanza de que esto se arregle en el estándar o en los navegadores que no sean Opera. Es solo un factor más que aleja a las personas de la autenticación básica HTTP en favor de esquemas de autenticación basados en cookies no estándar y menos accesibles. Qué vergüenza.

 52
Author: bobince,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-31 22:39:30

Es un defecto conocido que la autenticación básica no proporciona soporte para caracteres que no sean ISO-8859-1.

Se sabe que algunos UAS usan UTF-8 en su lugar (Opera viene a la mente), pero tampoco hay interoperabilidad para eso.

Por lo que puedo decir, no hay manera de arreglar esto, excepto definiendo un nuevo esquema de autenticación que maneje todo Unicode. Y conseguir que se despliegue.

 5
Author: Julian Reschke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-31 20:19:20

La autenticación HTTP Digest tampoco es una solución para este problema. Sufre del mismo problema de que el cliente no puede decirle al servidor qué conjunto de caracteres está utilizando y el servidor no puede asumir correctamente lo que usó el cliente.

 3
Author: Leif Wickland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-20 20:16:57

¿Has probado usando algo como curl para asegurarte de que no es un problema con Firefox? El HTTP Auth RFC es silencioso en ASCII vs.no ASCII, pero dice que el valor pasado en el encabezado es el nombre de usuario y la contraseña separados por dos puntos, y no puedo encontrar dos puntos en la cadena que Firefox está enviando.

 0
Author: Hank Gay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-31 19:41:36

Si está codificando para Windows 8.1, tenga en cuenta que el ejemplo de la documentación para HttpCredentialsHeaderValue está utilizando (erróneamente) la codificación UTF-16. Una solución razonablemente buena es cambiar a UTF-8 (ya que ISO-8859-1 no es compatible con CryptographicBuffer.ConvertStringToBinary).

Véase http://msdn.microsoft.com/en-us/library/windows/apps/windows.web.http.headers.httpcredentialsheadervalue.aspx.

 0
Author: Tomas Karban,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-23 17:30:57

Podría ser un ignorante total, pero llegué a este post mientras buscaba un problema mientras enviaba una cadena UTF8 como encabezado dentro de una llamada ajax.

Podría resolver mi problema codificando en Base64 la cadena justo antes de enviarla. Eso significa que podría con un simple JS convertir el formulario a base64 justo antes de enviarlo y de esa manera puede ser conevrted de nuevo en el lado del servidor.

Estas sencillas herramientas me permitieron enviar cadenas utf8 como ASCII simple. Encontré que gracias a esta simple frase:

Base64 (esta codificación está diseñada para que los datos binarios sobrevivan al transporte a través de capas de transporte que no están limpias en 8 bits). http://www.webtoolkit.info/javascript-base64.html

Espero que esto ayude de alguna manera. Sólo tratando de devolverle un poco a la comunidad!

 -1
Author: David Pelaez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-29 03:01:03