Suprimir caixa de diálogo NTLM após solicitação não autorizada
-
09-06-2019 - |
Pergunta
Em um projeto recente do SharePoint, implementei uma webpart de autenticação que deve substituir a caixa de diálogo de autenticação NTLM.Funciona bem desde que o usuário forneça credenciais válidas.Sempre que o usuário fornece credenciais inválidas, a caixa de diálogo NTLM aparece no Internet Explorer.
Meu código Javascript que faz a autenticação via XmlHttpRequest fica assim:
function Login() {
var request = GetRequest(); // retrieves XmlHttpRequest
request.onreadystatechange = function() {
if (this.status == 401) { // unauthorized request -> invalid credentials
// do something to suppress NTLM dialog box...
// already tried location.reload(); and window.location = <url to authentication form>;
}
}
request.open("GET", "http://myServer", false, "domain\\username", "password");
request.send(null);
}
Não quero que a caixa de diálogo NTLM seja exibida quando o usuário fornecer credenciais inválidas.Em vez disso, o postback pelo botão de login no formulário de autenticação deve ser executado.Em outras palavras, o navegador não deve saber da minha solicitação não autorizada.
Existe alguma maneira de fazer isso via Javascript?
Solução
Marcao comentário de está correto;O prompt de autenticação NTLM é acionado por um código de resposta 401 e pela presença de NTLM como o primeiro mecanismo oferecido no cabeçalho WWW-Authenticate (Ref: O protocolo de autenticação NTLM).
Não tenho certeza se entendi a descrição da pergunta corretamente, mas acho que você está tentando encapsular a autenticação NTLM para SharePoint, o que significa que você não tem controle sobre o protocolo de autenticação do lado do servidor, correto?Se você não conseguir manipular o lado do servidor para evitar o envio de uma resposta 401 em credenciais com falha, não poderá evitar esse problema, porque faz parte da especificação (do lado do cliente):
O objeto XMLHttpRequest
Se o UA suportar autenticação HTTP [RFC2617], ele deve considerar solicitações originárias desse objeto como parte do espaço de proteção que inclui os URIs acessados e enviar cabeçalhos de autorização e lidar com as solicitações não autorizadas 401 adequadamente.se a autenticação falhar, os UAs deverão solicitar credenciais aos usuários.
Portanto, a especificação na verdade exige que o navegador avise o usuário adequadamente se qualquer resposta 401 for recebida em um XMLHttpRequest, como se o usuário tivesse acessado o URL diretamente.Até onde eu sei, a única maneira de realmente evitar isso seria você ter controle sobre o lado do servidor e evitar respostas 401 não autorizadas, como Mark mencionou.
Um último pensamento é que você pode contornar isso usando um proxy, como um script separado do lado do servidor em outro servidor da web.Esse script então pega um usuário e passa um parâmetro e verifica a autenticação, para que o navegador do usuário não seja o que está fazendo a solicitação HTTP original e, portanto, não esteja recebendo a resposta 401 que está causando o prompt.Se você fizer isso dessa maneira, poderá descobrir no script "proxy" se ele falhou e, em caso afirmativo, avisar o usuário novamente até que seja bem-sucedido.Em um evento de autenticação bem-sucedido, você pode simplesmente buscar a solicitação HTTP como está agora, pois tudo funciona se as credenciais forem especificadas corretamente.
Outras dicas
IIRC, o navegador abre a caixa de diálogo de autenticação quando o seguinte retorna no fluxo de solicitação:
- Status HTTP de 401
- Cabeçalho WWW-Authenticate
Eu acho que você precisaria suprimir um ou ambos.A maneira mais fácil de fazer isso é ter um método de login que use um nome de usuário e senha Base64 (você está usando HTTPS, certo?) E retorne 200 com um status válido/inválido.Depois que a senha for validada, você poderá usá-la com o XHR.
Consegui fazer isso funcionar para todos os navegadores, exceto o Firefox.Veja minha postagem no blog abaixo de alguns anos atrás.Minha postagem é voltada apenas para o IE, mas com algumas pequenas alterações no código, ela deve funcionar no Chrome e no Safari.
http://steve.thelineberrys.com/ntlm-login-with-anonymous-fallback-2/
EDITAR:
A essência da minha postagem é agrupar sua chamada JS xml em uma instrução try catch.No IE, Chrome e Safari, isso suprimirá a caixa de diálogo NTLM.Não parece funcionar como esperado no Firefox.