it-swarm-pt.tech

Como posso suprimir o diálogo de autenticação do navegador?

Meu aplicativo da web tem uma página de login que envia credenciais de autenticação por meio de uma chamada AJAX. Se o usuário digitar o nome de usuário e a senha corretos, tudo estará bem, mas se não, acontece o seguinte:

  1. O servidor da web determina que, embora a solicitação inclua um cabeçalho de autorização bem formado, as credenciais no cabeçalho não são autenticadas com êxito.
  2. O servidor da web retorna um código de status 401 e inclui um ou mais cabeçalhos WWW-Authenticate listando os tipos de autenticação suportados.
  3. O navegador detecta que a resposta à minha chamada no objeto XMLHttpRequest é 401 e a resposta inclui cabeçalhos WWW-Authenticate. Em seguida, aparece uma caixa de diálogo de autenticação pedindo, novamente, o nome de usuário e a senha.

Tudo bem até o passo 3. Não quero que a caixa de diálogo apareça, quero manipular a resposta 401 em minha função de retorno de chamada AJAX. (Por exemplo, exibindo uma mensagem de erro na página de login.) Eu quero que o usuário digite novamente seu nome de usuário e senha, é claro, mas eu quero que eles vejam meu formulário de login amigável e reconfortante, e não o feio do navegador, padrão diálogo de autenticação.

Incidentalmente, não tenho controle sobre o servidor, portanto, tê-lo retornar um código de status personalizado (ou seja, algo diferente de um 401) não é uma opção.

Existe alguma maneira eu posso suprimir o diálogo de autenticação? Em particular, posso suprimir a caixa de diálogo Autenticação necessária no Firefox 2 ou posterior? Existe alguma maneira de suprimir a caixa de diálogo Conectar a [Host] em IE 6 e posterior?


Editar
Informações adicionais do autor (18 de setembro):
Devo acrescentar que o problema real da janela de autenticação do navegador é que ela fornece informações insuficientes ao usuário.

O usuário acaba de digitar um nome de usuário e senha através do formulário na página de login, ele acredita que ele digitou os dois corretamente, e ele clicou no botão de envio ou aperte enter. Sua expectativa é de que ele seja levado para a próxima página ou talvez seja informado de que ele digitou suas informações incorretamente e deve tentar novamente. No entanto, ele é apresentado com uma caixa de diálogo inesperada.

A caixa de diálogo não reconhece o fato de que ele apenas fez digitar um nome de usuário e senha. Não indica claramente que houve um problema e que ele deveria tentar novamente. Em vez disso, a caixa de diálogo apresenta ao usuário informações secretas, como "O site diz: '[realm]'". Onde [realm] é um nome curto que somente um programador poderia amar.

Os projetistas de broswer da Web tomam nota: ninguém perguntaria como suprimir a caixa de diálogo de autenticação se a caixa de diálogo fosse simplesmente mais fácil de usar. A razão entire que estou fazendo um formulário de login é que nossa equipe de gerenciamento de produtos considera, com razão, que os diálogos de autenticação dos navegadores são terríveis.

72
dgvid

Eu não acho que isso é possível - se você usar a implementação do cliente HTTP do navegador, ele sempre irá aparecer na caixa de diálogo. Dois hacks vêm à mente:

  1. Talvez Flash lide com isso de forma diferente (ainda não tentei), então ter um filme em flash faz com que o pedido possa ajudar.

  2. Você pode configurar um 'proxie' para o serviço que está acessando em seu próprio servidor e modificá-lo um pouco, para que o navegador não os reconheça.

17
Marijn

Eu encontrei o mesmo problema aqui, e o engenheiro de back-end da minha empresa implementou um comportamento que aparentemente é considerado uma boa prática: quando uma chamada para uma URL retorna um 401, se o cliente tiver definido o cabeçalho X-Requested-With: XMLHttpRequest, o servidor descartará o cabeçalho www-authenticate em sua resposta. 

O efeito colateral é que o popup de autenticação padrão não aparece.

Certifique-se de que sua chamada de API tenha o cabeçalho X-Requested-With definido como XMLHttpRequest. Se assim for, não há nada a fazer além de mudar o comportamento do servidor de acordo com essa boa prática ...

44
Antoine Banctel-Chevrel

O navegador exibe um prompt de login quando ambas as condições a seguir forem atendidas:

  1. O status HTTP é 4xx
  2. WWW-Authenticate header está presente na resposta

Se você pode controlar a resposta HTTP, então você pode remover o cabeçalho WWW-Authenticate da resposta, e o navegador não irá aparecer o diálogo de login.

Se você não puder controlar a resposta, poderá configurar um proxy para filtrar o cabeçalho WWW-Authenticate da resposta.

Tanto quanto eu sei (sinta-se livre para me corrigir se eu estiver errado), não há maneira de impedir o prompt de login, uma vez que o navegador recebe o cabeçalho WWW-Authenticate.

14
rustyx

Eu percebo que esta pergunta e suas respostas são muito antigas. Mas acabei aqui. Talvez outros também o façam.

Se você tiver acesso ao código do serviço da Web que está retornando o 401. Basta alterar o serviço para retornar 403 (Proibido) nessa situação, em vez de 401. O navegador não solicitará credenciais em resposta a um 403. 403 é o código correto para um usuário autenticado que não está autorizado para um recurso específico. Qual parece ser a situação do OP.

Do documento da IETF em 403:

Um servidor que recebe credenciais válidas que não são adequadas para Obter acesso deve responder com o código de status 403 (Proibido)

5
Jim Reineri

No Mozilla, você pode alcançá-lo com o seguinte script ao criar o objeto XMLHttpRequest:

xmlHttp=new XMLHttpRequest();
xmlHttp.mozBackgroundRequest = true;
xmlHttp.open("GET",URL,true,USERNAME,PASSWORD);
xmlHttp.send(null);

A segunda linha impede a caixa de diálogo ....

4
Yogesh

Qual tecnologia de servidor você usa e há um produto específico que você usa para autenticação?

Como o navegador está apenas fazendo seu trabalho, acredito que você tenha que alterar as coisas no lado do servidor para não retornar um código de status 401. Isso pode ser feito usando formulários de autenticação personalizados que simplesmente retornam o formulário novamente quando a autenticação falha.

3
jan.vdbergh

jan.vdbergh tem a verdade, se você pode mudar o 401 no lado do servidor para outro código de status, o navegador não vai pegar e pintar o pop-up. Outra solução poderia ser mudar o cabeçalho WWW-Authenticate para outro cabeçalho personalizado. Eu não acredito porque o navegador diferente não pode suportá-lo, em algumas versões do Firefox, podemos fazer o pedido xhr com mozBackgroundRequest, mas nos outros navegadores ?? aqui, há um interessante link com esse problema no Chromium.

2
Kalamarico

No Mozilla, configurar o parâmetro mozBackgroundRequest de XMLHttpRequest ( docs ) como true suprime esses diálogos e faz com que os pedidos simplesmente falhem. No entanto, não sei quão bom é o suporte a vários navegadores (incluindo se a qualidade das informações de erro nessas solicitações com falha é muito boa nos navegadores).

2
rakslice

Eu tenho esse mesmo problema com MVC 5 e VPN, onde sempre que estamos fora do DMZ usando a VPN, nos encontramos ter que responder a esta mensagem do navegador. Usando .net eu simplesmente manipulo o roteamento do erro usando

<customErrors defaultRedirect="~/Error"  >
  <error statusCode="401" redirect="~/Index"/>
</customErrors>

até agora, funcionou porque a ação Index sob o controlador home valida o usuário. A exibição nesta ação, se o logon não for bem-sucedida, possui controles de login que utilizo para registrar o usuário usando a consulta LDAP passada nos Serviços de Diretório:

      DirectoryEntry entry = new DirectoryEntry("LDAP://OurDomain");
      DirectorySearcher Dsearch = new DirectorySearcher(entry);
      Dsearch.Filter = "(SAMAccountName=" + UserID + ")";
      Dsearch.PropertiesToLoad.Add("cn");

Enquanto isso tem funcionado bem até agora, e devo deixar você saber que eu ainda estou testando e o código acima não teve nenhum motivo para ser executado, por isso está sujeito à remoção ... o teste atualmente inclui a tentativa de descobrir um caso em que o segundo conjunto de código é de qualquer outro uso. Mais uma vez, este é um trabalho em progresso, mas como poderia ser de alguma ajuda ou fazer algumas idéias para o seu cérebro, eu decidi adicioná-lo agora ... Eu atualizarei com os resultados finais assim que todos os testes forem feitos.

1
Clarence

Eu estou usando o Node, Express e Passport e estava lutando com o mesmo problema. Eu tenho que trabalhar explicitamente configurando o cabeçalho www-authenticate para uma string vazia. No meu caso, ficou assim:

(err, req, res, next) => {
  if (err) {
    res._headers['www-authenticate'] = ''
    return res.json(err)
  }
}

Espero que ajude alguém!

0
John Knotts

Para aqueles unsing C # aqui está ActionAttribute que retorna 400 em vez de 401 e 'engole' diálogo de autenticação básica.

public class NoBasicAuthDialogAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
        filterContext.Result = new HttpStatusCodeResult(400);
    }
}

use como segue:

[NoBasicAuthDialogAuthorize(Roles = "A-Team")]
public ActionResult CarType()
{
 // your code goes here
}

Espero que isso economize algum tempo.

0
Matas Vaitkevicius