Também disponível em: English · Español · Français · العربية
WWW-Authenticate: todos os desafios, não só o primeiro
Cole o cabeçalho de uma resposta 401 e veja cada desafio, cada parâmetro e o que o padrão diz a respeito.
O que é o cabeçalho WWW-Authenticate?
Quando um servidor responde a uma requisição com 401 Unauthorized, ele precisa dizer como você poderia se autenticar. É isso o cabeçalho WWW-Authenticate: uma lista de desafios, cada um nomeando um esquema como Basic ou Bearer e em geral carregando parâmetros como um realm. O cliente escolhe um esquema que entenda e responde com um cabeçalho Authorization.
O cabeçalho parece simples e não é. A própria RFC 9110 diz isso, aconselhando que os agentes de usuário tenham cuidado especial ao analisá-lo, porque um valor pode conter mais de um desafio, cada desafio pode carregar uma lista de parâmetros separados por vírgulas, e o cabeçalho pode ser enviado várias vezes. O separador entre desafios e o separador entre parâmetros são o mesmo caractere, então nada indica localmente qual dos dois é uma vírgula específica.
Esta página implementa a gramática da especificação, mostra todos os desafios e não apenas o primeiro, e nomeia cada parâmetro com a forma em que ele chegou. Ela analisa o desafio que o servidor envia. Deliberadamente não decodifica um cabeçalho Authorization, que é a resposta que carrega suas credenciais.
Como usar
- Cole o cabeçalho. Com ou sem o nome do campo, um por linha se a resposta enviou mais de um. Vários cabeçalhos e um único valor separado por vírgulas são equivalentes pelo padrão, então dão a mesma resposta.
- Leia os desafios. Cada um mostra seu esquema, se esse esquema está no registro da IANA, e uma tabela de parâmetros indicando se cada valor chegou como token sem aspas, como string entre aspas, ou entre aspas com um escape dentro.
- Confira as notas abaixo. Elas cobrem aquilo sobre o que o padrão tem uma opinião: mais de um desafio por linha, um esquema não registrado, uma vírgula solta, um parâmetro repetido, ou um esquema conhecido que não vem primeiro.
Por que este cabeçalho é difícil de analisar
A especificação dá um exemplo resolvido e, de forma incomum, diz a resposta. Ela mostra um desafio Basic com realm igual a simple, seguido de um desafio Newauth com realm igual a apps, um parâmetro type e um parâmetro title, tudo numa linha. E afirma que isso são dois desafios, e que type e title pertencem ao segundo.
Chegar a isso exige um token de antecipação. Quando o analisador alcança type, nada antes dele diz se aquela palavra abre um terceiro desafio ou nomeia um parâmetro do segundo. Só o caractere seguinte decide: um token seguido de sinal de igual é um parâmetro, e um token seguido de qualquer outra coisa é um esquema novo. Ignore essa regra e você obtém uma análise plausível e simplesmente errada.
O mesmo exemplo carrega uma segunda armadilha. Seu parâmetro title é uma string entre aspas que contém aspas, escapadas com barras invertidas. Um analisador construído em torno de casar de uma aspa até a próxima para no lugar errado, e uma vírgula dentro de um valor entre aspas divide um desafio que deveria ter ficado inteiro.
Não é uma preocupação teórica. Enquanto esta página era construída, dois analisadores publicados foram testados contra o exemplo da própria especificação. Nenhum devolveu a resposta que a especificação imprime: um relatou um único desafio com os dois realms fundidos, e o outro não devolveu nada, apesar de lidar perfeitamente com um desafio Basic comum. O padrão previu isso, ao avisar que enviar mais de um desafio numa linha pode não ser interoperável, e à parte que muitos clientes falham com um esquema que não reconhecem.
O que esta página deliberadamente não faz
Ela não decodifica um cabeçalho Authorization. O WWW-Authenticate viaja do servidor e é público: é a pergunta. O Authorization viaja do cliente e carrega a resposta, que no caso do Basic é seu usuário e sua senha com um disfarce muito fino. Se você colar um aqui, a página avisa e para, sem decodificá-lo. É a mesma posição que este site mantém em seu decodificador de JWT, que não tem campo para a chave de assinatura: colar uma credencial em qualquer lugar é um hábito que não vale a pena adquirir, nem mesmo numa página que roda inteiramente no seu próprio navegador.
Ela diz o que a gramática diz, não o que seu cliente vai fazer. Um desafio pode ser perfeitamente válido e ainda assim ser ignorado, porque um navegador só implementa um punhado de esquemas e uma biblioteca pode parar no primeiro desafio que reconhece. Nada aqui foi medido contra um navegador, e esta página não faz afirmação alguma sobre um.
Ela também não julga a ausência de realm. É tentador tratar isso como erro, mas o padrão descreve o parâmetro realm como reservado para esquemas que queiram indicar um escopo de proteção, não como algo que todo desafio precise carregar. Onde a especificação se abstém de exigir, esta página se abstém de avisar.
Um caso é genuinamente ambíguo e é relatado em vez de resolvido. Um sinal de igual final após um nome solto, como um desafio que termina em realm=, casa com a gramática de um token opaco tão bem quanto com a de um parâmetro que ficou sem valor, porque aquela produção é uma sequência de caracteres seguida de qualquer número de sinais de igual. Naquele ponto do texto nada os distingue. Onde o padrão deixa duas leituras em aberto, esta página também deixa.
Por que é grátis?
Analisar um cabeçalho é manipulação de strings, e acontece no seu navegador. Não há servidor no meio, então não há o que cobrar nem conta a criar.
Nada é enviado. O cabeçalho que você cola não sai da aba.