RFC2617 говорит, что нужно кодировать имя пользователя и пароль в base64, но не говорит, какую кодировку символов использовать при создании октетов для ввода в алгоритм base64.
Должен ли я использовать US-ASCII или UTF8? Или кто-то уже где-то уладил этот вопрос?
http
basic-authentication
Добс Вандермейер
источник
источник
Ответы:
Исходная спецификация - RFC 2617
RFC 2617 можно читать как «ISO-8859-1» или «undefined». Твой выбор. Известно, что многие серверы используют ISO-8859-1 (нравится вам это или нет) и не работают, когда вы отправляете что-то еще. Так что, вероятно, единственный безопасный выбор - придерживаться ASCII.
Для получения дополнительной информации и предложения по исправлению ситуации см. Черновик «Параметр кодирования для базовой аутентификации HTTP» (который лег в основу RFC 7617).
Новый - RFC 7617
С 2015 года существует RFC 7617 , который отменяет RFC 2617. В отличие от старого RFC, новый RFC явно определяет кодировку символов, которая будет использоваться для имени пользователя и пароля.
charset="UTF-8"
в своем запросе, например:WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
Это объявляет, что сервер будет принимать символы, отличные от ASCII, в имени пользователя / пароле и ожидает, что они будут закодированы в UTF-8 (в частности, форма нормализации C) . Обратите внимание, что разрешен только UTF-8.
Полная версия:
Прочтите спецификацию . Если содержит дополнительные сведения, такие как точная процедура кодирования и список кодовых точек Unicode, которые должны поддерживаться.
Поддержка браузера
По состоянию на 2018 год современные браузеры обычно по умолчанию используют UTF-8, если пользователь вводит символы, отличные от ASCII, для имени пользователя или пароля (даже если сервер не использует
charset
параметр).Царство
Параметр области по- прежнему поддерживает только символы ASCII даже в RFC 7617.
источник
Краткий ответ: iso-8859-1, если не используются закодированные слова в соответствии с RFC2047 (MIME).
Более длинное объяснение:
RFC2617, раздел 2 (HTTP-аутентификация) определяет базовые учетные данные :
Спецификацию не следует читать без ссылки на RFC2616 (HTTP 1.1) для определений в BNF (например, приведенное выше):
RFC2616, раздел 2.1 определяет ТЕКСТ (выделено мной):
Так что это определенно iso-8859-1, если вы не обнаружите другую кодировку в соответствии с правилами RFC2047 (MIME pt. 3):
В этом случае знак евро в слове будет закодирован в
0xA4
соответствии с ISO-8859-15 . Насколько я понимаю, вы должны проверить эти закодированные разделители слов, а затем декодировать слова внутри на основе указанной кодировки. Если вы этого не сделаете, вы подумаете, что это пароль=?iso-8859-15?q?T¤ST?=
(обратите внимание, что0xA4
он будет декодирован в¤
при интерпретации как iso-8859-1).Я так понимаю, я не могу найти более явного подтверждения, чем эти RFC. И некоторые из них кажутся противоречивыми. Например, одна из 4 заявленных целей RFC2047 (MIME, pt. 3) - переопределить:
Но тогда RFC2616 (HTTP 1.1) определяет заголовок, используя правило TEXT, которое по умолчанию имеет значение iso-8859-1. Означает ли это, что каждое слово в этом заголовке должно быть закодированным словом (т.е.
=?...?=
формой)?Также важно, что ни один текущий браузер этого не делает. Они используют utf-8 (Chrome, Opera), iso-8859-1 (Safari), системную кодовую страницу (IE) или что-то еще (например, только самый старший бит из utf-8 в случае Firefox).
Изменить: я только что понял, что этот ответ больше смотрит на проблему с точки зрения сервера.
источник
РЛК в сторону, в Spring Framework , в
BasicAuthenticationFilter
классе, по умолчанию UTF-8 .Я считаю, что причиной этого выбора является то, что UTF-8 может кодировать все возможные символы, а ISO-8859-1 (или ASCII) - нет. Попытка использовать имя пользователя / пароль с символами, не поддерживаемыми в системе, может привести к нарушению поведения или (что еще хуже) к снижению безопасности.
источник
Если вас интересует, что делают браузеры, когда вы вводите символы, отличные от ascii, в приглашении входа в систему, я просто попробовал с Firefox.
Кажется, что он лениво конвертирует все в ISO-8859-1, беря младший байт каждого значения Unicode, например:
Кодируются так же, как:
0x5a 0x3a 0x4e base64-> WjpO
источник