O RFC2617 diz para codificar o nome de usuário e a senha para base64, mas não diz qual codificação de caracteres usar ao criar os octetos para entrada no algoritmo de base64.
Devo assumir US-ASCII ou UTF8? Ou alguém já resolveu essa questão em algum lugar?
http
basic-authentication
Dobes Vandermeer
fonte
fonte
Respostas:
Especificação original - RFC 2617
RFC 2617 pode ser lido como "ISO-8859-1" ou "indefinido". Sua escolha. É sabido que muitos servidores usam ISO-8859-1 (goste ou não) e irão falhar quando você enviar algo diferente. Portanto, provavelmente a única escolha segura é seguir o ASCII.
Para obter mais informações e uma proposta para corrigir a situação, consulte o rascunho "Um parâmetro de codificação para autenticação básica de HTTP" (que formou a base para RFC 7617).
Novo - RFC 7617
Desde 2015 existe o RFC 7617 , que torna o RFC 2617 obsoleto. Em contraste com o RFC antigo, o novo RFC define explicitamente a codificação de caracteres a ser usada para nome de usuário e senha.
charset="UTF-8"
em seu desafio, como este:WWW-Authenticate: Basic realm="myChosenRealm", charset="UTF-8"
Isso anuncia que o servidor aceitará caracteres não ASCII no nome de usuário / senha e que espera que eles sejam codificados em UTF-8 (especificamente Formulário C de normalização) . Observe que apenas UTF-8 é permitido.
Versão completa:
Leia as especificações . Se contém detalhes adicionais, como o procedimento de codificação exato e a lista de pontos de código Unicode que devem ser suportados.
Suporte de navegador
A partir de 2018, os navegadores modernos normalmente usarão UTF-8 como padrão se um usuário inserir caracteres não ASCII para nome de usuário ou senha (mesmo se o servidor não usar o
charset
parâmetro).Reino
O parâmetro realm ainda suporta apenas caracteres ASCII, mesmo no RFC 7617.
fonte
Resposta curta: iso-8859-1 a menos que palavras codificadas sejam usadas de acordo com RFC2047 (MIME).
Explicação mais longa:
RFC2617, seção 2 (autenticação HTTP) define as credenciais básicas :
A especificação não deve ser lida sem se referir a RFC2616 (HTTP 1.1) para definições em BNF (como a acima):
RFC2616, seção 2.1 define TEXTO (grifo meu):
Portanto, é definitivamente iso-8859-1, a menos que você detecte alguma outra codificação de acordo com as regras RFC2047 (MIME pt. 3):
Neste caso, o sinal do euro na palavra seria codificado de
0xA4
acordo com a iso-8859-15 . É meu entendimento que você deve verificar esses delimitadores de palavras codificadas e, em seguida, decodificar as palavras internas com base na codificação especificada. Do contrário, você pensará que a senha é=?iso-8859-15?q?T¤ST?=
(observe que0xA4
seria decodificada para¤
quando interpretada como iso-8859-1).Pelo que entendi, não consigo encontrar uma confirmação mais explícita do que essas RFCs. E algumas coisas parecem contraditórias. Por exemplo, um dos 4 objetivos declarados da RFC2047 (MIME, pt. 3) é redefinir:
Mas então o RFC2616 (HTTP 1.1) define um cabeçalho usando a regra TEXT, cujo padrão é iso-8859-1. Isso significa que cada palavra neste cabeçalho deve ser uma palavra codificada (ou seja, a
=?...?=
forma)?Também relevante, nenhum navegador atual faz isso. Eles usam utf-8 (Chrome, Opera), iso-8859-1 (Safari), a página de código do sistema (IE) ou outra coisa (como apenas o bit mais significativo de utf-8 no caso do Firefox).
Edit: Acabei de perceber que esta resposta aborda o problema mais da perspectiva do lado do servidor.
fonte
RFCs à parte, no framework Spring , a
BasicAuthenticationFilter
classe, o padrão é UTF-8 .Acredito que a razão para essa escolha é que UTF-8 é capaz de codificar todos os caracteres possíveis, enquanto ISO-8859-1 (ou ASCII) não é. Tentar usar nome de usuário / senha com caracteres não suportados no sistema pode levar a um comportamento quebrado ou (talvez pior) degradação da segurança.
fonte
Se você estiver interessado em saber o que os navegadores fazem quando você insere caracteres não ascii no prompt de login, acabei de tentar com o Firefox.
Parece converter preguiçosamente tudo para ISO-8859-1, tomando o byte menos significativo de cada valor Unicode, por exemplo:
São codificados da mesma forma que:
0x5a 0x3a 0x4e base64-> WjpO
fonte