RFC2617 mówi, że należy zakodować nazwę użytkownika i hasło do base64, ale nie mówi, jakiego kodowania znaków użyć podczas tworzenia oktetów do wprowadzenia do algorytmu base64.
Czy powinienem założyć US-ASCII czy UTF8? A może ktoś już gdzieś rozstrzygnął tę kwestię?
http
basic-authentication
Dobes Vandermeer
źródło
źródło
Odpowiedzi:
Oryginalna specyfikacja - RFC 2617
RFC 2617 można odczytać jako „ISO-8859-1” lub „niezdefiniowany”. Twój wybór. Wiadomo, że wiele serwerów używa ISO-8859-1 (podoba lub nie) i zawiedzie, gdy wyślesz coś innego. Więc prawdopodobnie jedynym bezpiecznym wyborem jest trzymanie się ASCII.
Aby uzyskać więcej informacji i propozycję rozwiązania problemu, zobacz wersję roboczą „Parametr kodowania dla podstawowego uwierzytelniania HTTP” (który stanowił podstawę dla RFC 7617).
Nowość - RFC 7617
Od 2015 roku istnieje RFC 7617 , który zastępuje RFC 2617. W przeciwieństwie do starego RFC, nowy RFC wyraźnie definiuje kodowanie znaków, które mają być używane dla nazwy użytkownika i hasła.
charset="UTF-8"
w swoim wezwaniu, na przykład:WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
To ogłasza, że serwer zaakceptuje znaki inne niż ASCII w nazwie użytkownika / haśle i oczekuje, że zostaną one zakodowane w UTF-8 (w szczególności formularz normalizacji C) . Zwróć uwagę, że dozwolony jest tylko UTF-8.
Pełna wersja:
Przeczytaj specyfikację . Jeśli zawiera dodatkowe szczegóły, takie jak dokładna procedura kodowania i lista punktów kodowych Unicode, które powinny być obsługiwane.
Wsparcie przeglądarki
Począwszy od 2018 r., Nowoczesne przeglądarki będą zwykle domyślnie używać UTF-8, jeśli użytkownik wprowadzi znaki inne niż ASCII jako nazwę użytkownika lub hasło (nawet jeśli serwer nie używa tego
charset
parametru).Królestwo
Sfera parametr nadal obsługuje tylko znaki ASCII nawet w dokumencie RFC 7617.
źródło
Krótka odpowiedź: iso-8859-1, chyba że zakodowane słowa są używane zgodnie z RFC2047 (MIME).
Dłuższe wyjaśnienie:
RFC2617, sekcja 2 (Uwierzytelnianie HTTP) definiuje podstawowe poświadczenia :
Specyfikacji nie należy czytać bez odwołania się do RFC2616 (HTTP 1.1) dla definicji w BNF (jak powyższa):
RFC2616, sekcja 2.1 definiuje TEKST (moje wyróżnienie ):
Jest to więc zdecydowanie iso-8859-1, chyba że wykryjesz inne kodowanie zgodne z regułami RFC2047 (MIME pkt 3):
W takim przypadku znak euro w słowie byłby zakodowany
0xA4
zgodnie z ISO-8859-15 . Rozumiem, że należy sprawdzić te zakodowane ograniczniki słów, a następnie zdekodować zawarte w nich słowa w oparciu o określone kodowanie. Jeśli tego nie zrobisz, pomyślisz, że hasło to=?iso-8859-15?q?T¤ST?=
(uwaga,0xA4
które zostanie zdekodowane,¤
gdy zostanie zinterpretowane jako iso-8859-1).To jest moje rozumienie, nie mogę znaleźć bardziej wyraźnego potwierdzenia niż te RFC. A niektóre z nich wydają się sprzeczne. Na przykład jednym z 4 określonych celów RFC2047 (MIME, pkt 3) jest przedefiniowanie:
Ale potem RFC2616 (HTTP 1.1) definiuje nagłówek przy użyciu reguły TEXT, która domyślnie jest ustawiona na iso-8859-1. Czy to oznacza, że każde słowo w tym nagłówku powinno być zakodowanym słowem (tj.
=?...?=
Formą)?Co więcej, żadna obecna przeglądarka tego nie robi. Używają utf-8 (Chrome, Opera), iso-8859-1 (Safari), strony kodowej systemu (IE) lub czegoś innego (jak tylko najbardziej znaczący bit z utf-8 w przypadku Firefoksa).
Edycja: właśnie zdałem sobie sprawę, że ta odpowiedź przedstawia problem bardziej z perspektywy serwera.
źródło
RFC bok, w Spring Framework , w
BasicAuthenticationFilter
klasie, domyślnie jest UTF-8 .Uważam, że powodem tego wyboru jest to, że UTF-8 jest w stanie zakodować wszystkie możliwe znaki, podczas gdy ISO-8859-1 (lub ASCII) nie. Próba użycia nazwy użytkownika / hasła ze znakami nieobsługiwanymi w systemie może prowadzić do nieprawidłowego zachowania lub (co gorsza) obniżenia bezpieczeństwa.
źródło
Jeśli jesteś zainteresowany tym, co robią przeglądarki, gdy wpisujesz znaki inne niż ASCII w monicie logowania, właśnie spróbowałem z Firefoksem.
Wydaje się, że leniwie konwertuje to wszystko na ISO-8859-1, pobierając najmniej znaczący bajt z każdej wartości Unicode, np .:
Są zakodowane tak samo jak:
0x5a 0x3a 0x4e base64-> WjpO
źródło