UTF-8 символов, искаженных в имени пользователя HTTP Basic Auth - PullRequest
27 голосов
/ 31 марта 2009

Я пытаюсь создать веб-сервис, используя Ruby on Rails. Пользователи аутентифицируют себя через HTTP Basic Auth. Я хочу разрешить любые допустимые символы UTF-8 в именах пользователей и паролях.

Проблема в том, что браузер искажает символы в учетных данных Basic Auth перед отправкой их в мой сервис. Для тестирования, я использую 'カ タ カ ナ カ タ カ ナ カ タ カ ナ カ タ カ ナ カ タ カ ナ カ タ カ ナ カ タ カ ナ カ タ カ ナ', как мое имя пользователя (понятия не имею, что это значит - AFAIK это несколько случайных символов наш QA парень придумал - пожалуйста, прости меня, если это как-то оскорбительно).

Если я воспринимаю это как строку и сделать username.unpack ( «ч *»), чтобы преобразовать его в шестнадцатеричном, я получаю: «3e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a83e28ba3e28fb3e28ba3e38a8» Это кажется о праве на 32 кандзи символов (3 байта / 6 шестнадцатеричных цифр в) .

Если я сделаю то же самое с именем пользователя, которое входит через HTTP Basic auth, я получу: 'Bafbbaacbafbbaacbafbbaacbafbbaacbafbbaacbafbbaacbafbbaacbafbbaac. Это явно намного короче. Используя плагин Firefox Live HTTP Headers, вот фактический отправляемый заголовок:

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

Похоже на эту строку 'bafbba ...', где поменялись местами верхний и нижний кусочки (по крайней мере, когда я вставляю ее в Emacs, декодирование base 64, затем переключаюсь в режим hexl) Это может быть представление имени пользователя в формате UTF16, но я не получил ничего, чтобы отобразить его как что-либо кроме бреда.

Rails устанавливает заголовок типа контента в UTF-8, поэтому браузер должен отправлять в этой кодировке. Я получаю правильные данные для отправки формы.

Проблема возникает как в Firefox 3.0.8, так и в IE 7.

Итак ... есть ли волшебный соус для того, чтобы веб-браузеры отправляли символы UTF-8 через HTTP Basic Auth? Я принимаю вещи неправильно на принимающей стороне? HTTP Basic Auth просто не работает с не-ASCII символами?

Ответы [ 6 ]

53 голосов
/ 01 апреля 2009

Я хочу разрешить любые допустимые символы UTF-8 в именах пользователей и паролях.

Оставь все надежды. Базовая аутентификация и Unicode не смешиваются.

Не существует стандартного (*) для кодирования символов, отличных от ASCII, в имя пользователя Basic Authentication: токен пароля перед его шифрованием. Следовательно, каждый браузер делает что-то свое:

  • Opera использует UTF-8;
  • IE использует системную кодовую страницу по умолчанию (которую вы не можете знать, кроме как UTF-8) и молча искажает символы, которые ему не подходят, с помощью Windows угадывает случайный символ, который выглядит как немного похоже на тот, который вы хотели или, возможно, просто не секретный рецепт;
  • Mozilla использует только младший байт символьных кодовых точек, что приводит к кодированию по ISO-8859-1 и безвозвратному искажению символов, отличных от 8859-1 ... за исключением при выполнении XMLHttpRequests, в в каком случае он использует UTF-8;
  • Safari и Chrome кодируют в соответствии с ISO-8859-1 и вообще не могут отправлять заголовок авторизации, если используется символ, отличный от 8859-1.

*: некоторые люди интерпретируют стандарт, говоря, что либо:

  • это всегда должен быть ISO-8859-1, поскольку это кодировка по умолчанию для включения необработанных 8-битных символов, непосредственно включенных в заголовки;
  • это должно быть как-то закодировано с использованием правил RFC2047.

Но ни одно из этих предложений не является темой для включения в токен аутентификации в кодировке base64, а ссылка на RFC2047 в спецификации HTTP действительно не работает вообще, поскольку все места, которые она может потенциально использоваться, явно запрещены правила «контекста атома» самого RFC2047, даже если заголовки HTTP соблюдают правила и расширения семейства RFC822, а они этого не делают.

В итоге: тьфу. Практически нет надежды на то, что это когда-либо будет исправлено в стандарте или в браузерах, кроме Opera. Это всего лишь еще один фактор, отталкивающий людей от базовой аутентификации HTTP в пользу нестандартных и менее доступных схем аутентификации на основе файлов cookie. Стыд действительно.

5 голосов
/ 01 апреля 2009

Известно, что обычная проверка подлинности не обеспечивает поддержку символов, отличных от ISO-8859-1.

Известно, что некоторые UA используют вместо этого UTF-8 (на ум приходит Opera), но для этого также нет возможности взаимодействия.

Насколько я могу судить, нет способа исправить это, кроме как путем определения новой схемы аутентификации, которая обрабатывает все Unicode. И его развертывание.

3 голосов
/ 21 августа 2010

HTTP Digest аутентификация также не является решением этой проблемы. Из-за той же проблемы клиент не может сообщить серверу, какой набор символов он использует, и сервер не может правильно предположить, что использовал клиент.

0 голосов
/ 23 октября 2013

Если вы кодируете для Windows 8.1, обратите внимание, что пример в документации для HttpCredentialsHeaderValue (ошибочно) использует кодировку UTF-16. Разумным решением будет переключиться на UTF-8 (поскольку ISO-8859-1 не поддерживается CryptographicBuffer.ConvertStringToBinary).

См. http://msdn.microsoft.com/en-us/library/windows/apps/windows.web.http.headers.httpcredentialsheadervalue.aspx.

0 голосов
/ 29 сентября 2011

Я могу быть совершенно невежественным, но я пришел к этому сообщению, когда искал проблему при отправке строки UTF8 в качестве заголовка внутри вызова ajax.

Я мог бы решить мою проблему, кодируя в Base64 строку прямо перед ее отправкой. Это означает, что вы можете с помощью простого JS преобразовать форму в base64 непосредственно перед отправкой, и таким образом ее можно будет вернуть обратно на стороне сервера.

Этот простой инструмент позволил мне посылать строки utf8 как простой ASCII. Я обнаружил, что благодаря этому простому предложению:

base64 (эта кодировка предназначена для того, чтобы двоичные данные выживали при транспортировке через транспортные уровни, которые не являются 8-битными чистыми). http://www.webtoolkit.info/javascript-base64.html

Надеюсь, это поможет как-то. Просто пытаюсь вернуть немного сообществу!

0 голосов
/ 31 марта 2009

Вы тестировали, используя что-то вроде curl, чтобы убедиться, что это не проблема Firefox? HTTP Auth RFC ничего не говорит о ASCII и не-ASCII, но в нем говорится, что значение, переданное в заголовке, представляет собой имя пользователя и пароль, разделенные двоеточием, и я не могу найти двоеточие в строка, которую Firefox сообщает об отправке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...