web-dev-qa-db-fra.com

Comment puis-je supprimer la boîte de dialogue d'authentification du navigateur?

Mon application Web comporte une page de connexion qui soumet les informations d'authentification via un appel AJAX. Si l'utilisateur entre le nom d'utilisateur et le mot de passe corrects, tout va bien, mais dans le cas contraire, les événements suivants se produisent:

  1. Le serveur Web détermine que, bien que la demande comprenne un en-tête d'autorisation bien formé, les informations d'identification contenues dans l'en-tête ne s'authentifient pas correctement.
  2. Le serveur Web renvoie un code d'état 401 et inclut un ou plusieurs en-têtes WWW-Authenticate répertoriant les types d'authentification pris en charge.
  3. Le navigateur détecte que la réponse à mon appel sur l'objet XMLHttpRequest est 401 et que la réponse comprend des en-têtes WWW-Authenticate. Il ouvre ensuite une boîte de dialogue d'authentification demandant à nouveau le nom d'utilisateur et le mot de passe.

Tout va bien jusqu'à l'étape 3. Je ne veux pas que la boîte de dialogue apparaisse, je veux gérer la réponse 401 dans ma fonction de rappel AJAX. (Par exemple, en affichant un message d'erreur sur la page de connexion.) Je souhaite que l'utilisateur ressaisisse son nom d'utilisateur et son mot de passe, mais je souhaite qu'ils voient mon formulaire de connexion convivial et rassurant, et non le navigateur déplaisant, par défaut. dialogue d'authentification.

Incidemment, je n’ai aucun contrôle sur le serveur. Par conséquent, le fait qu’il renvoie un code d’état personnalisé (c’est-à-dire autre chose qu’un 401) n’est pas une option.

Est-il possible de supprimer le dialogue d'authentification? En particulier, puis-je supprimer la boîte de dialogue Authentification requise dans Firefox 2 ou une version ultérieure? Existe-t-il un moyen de supprimer la boîte de dialogue Connexion à [hôte]} dans IE 6 et versions ultérieures?


Modifier
Informations complémentaires de l'auteur (18 sept.): _
Je devrais ajouter que le vrai problème avec la boîte de dialogue d’authentification du navigateur qui s’ouvre est qu’il donne des informations insuffisantes à l’utilisateur.

L'utilisateur vient d'entrer un nom d'utilisateur et un mot de passe via le formulaire de la page de connexion, il pense avoir correctement saisi les deux, et il a cliqué sur le bouton d'envoi ou appuyé sur Entrée. Il s'attend à ce qu'il soit redirigé vers la page suivante ou qu'il soit peut-être informé qu'il a mal saisi ses informations et qu'il devrait essayer à nouveau. Cependant, une boîte de dialogue inattendue lui est présentée.

La boîte de dialogue ne reconnaît pas le fait qu'il a simplement fait entrer un nom d'utilisateur et un mot de passe. Cela ne dit pas clairement qu'il y avait un problème et qu'il devrait réessayer. Au lieu de cela, la boîte de dialogue présente à l'utilisateur des informations cryptées telles que "Le site indique: '[domaine]". " Où (royaume) est un nom de domaine court que seul un programmeur peut aimer.

Les concepteurs de sites Web en prennent note: personne ne demanderait comment supprimer le dialogue d'authentification si celui-ci était simplement plus convivial. La entière raison pour laquelle je remplis un formulaire de connexion est que notre équipe de gestion de produits considère à juste titre que les dialogues d'authentification des navigateurs sont affreux.

72
dgvid

Je ne pense pas que cela soit possible. Si vous utilisez la mise en œuvre du client HTTP du navigateur, cette boîte de dialogue apparaîtra toujours. Deux hacks viennent à l’esprit:

  1. Peut-être que Flash gère cela différemment (je n'ai pas encore essayé), il serait donc utile de disposer d'une animation flash.

  2. Vous pouvez configurer une "proxy" pour le service auquel vous accédez sur votre propre serveur et lui demander de modifier un peu les en-têtes d'authentification, de sorte que le navigateur ne les reconnaisse pas.

17
Marijn

J'ai rencontré le même problème ici et l'ingénieur principal de mon entreprise a adopté un comportement qui est apparemment considéré comme une bonne pratique: lorsqu'un appel à une URL renvoie 401, si le client a défini l'en-tête X-Requested-With: XMLHttpRequest, le serveur supprime l'en-tête www-authenticate. dans sa réponse. 

L'effet secondaire est que la fenêtre contextuelle d'authentification par défaut n'apparaît pas.

Assurez-vous que l'en-tête X-Requested-With est défini sur XMLHttpRequest dans l'appel de votre API. Si c'est le cas, il n'y a rien d'autre à faire que de changer le comportement du serveur selon cette bonne pratique ...

44

Le navigateur affiche une invite de connexion lorsque les deux conditions suivantes sont remplies:

  1. Le statut HTTP est 4xx
  2. WWW-Authenticate en-tête est présent dans la réponse

Si vous pouvez contrôler la réponse HTTP, vous pouvez alors supprimer l'en-tête WWW-Authenticate de la réponse et le navigateur ne fera pas apparaître la boîte de dialogue de connexion.

Si vous ne pouvez pas contrôler la réponse, vous pouvez configurer un proxy pour filtrer l'en-tête WWW-Authenticate de la réponse.

Autant que je sache (n'hésitez pas à me corriger si je me trompe), il n'existe aucun moyen d'empêcher l'invite de connexion une fois que le navigateur a reçu l'en-tête WWW-Authenticate.

14
rustyx

Je me rends compte que cette question et ses réponses sont très anciennes. Mais je me suis retrouvé ici. Peut-être que d'autres le seront aussi.

Si vous avez accès au code du service Web renvoyant le numéro 401. Modifiez simplement le service pour renvoyer un numéro 403 (interdit) dans cette situation au lieu de 401. Le navigateur ne demandera pas d'informations d'identification en réponse à un numéro 403. code correct pour un utilisateur authentifié non autorisé pour une ressource spécifique. Ce qui semble être la situation du PO.

D'après le document IETF 403:

Un serveur qui reçoit des informations d'identification valides qui ne conviennent pas à obtenir un accès doit répondre avec le code de statut 403 (Interdit)

5
Jim Reineri

Dans Mozilla, vous pouvez y parvenir avec le script suivant lorsque vous créez l'objet XMLHttpRequest:

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

La 2ème ligne empêche la boîte de dialogue ....

4
Yogesh

Quelle technologie de serveur utilisez-vous et utilisez-vous un produit en particulier pour l'authentification?

Étant donné que le navigateur ne fait que son travail, je pense que vous devez changer les choses côté serveur pour ne pas renvoyer un code d'état 401. Cela peut être fait à l'aide de formulaires d'authentification personnalisés qui renvoient simplement le formulaire à nouveau lorsque l'authentification échoue.

3
jan.vdbergh

jan.vdbergh a la vérité, si vous pouvez remplacer le code 401 côté serveur par un autre code d'état, le navigateur ne détectera pas et ne peindra pas la fenêtre contextuelle . Une autre solution pourrait être de changer l'en-tête WWW-Authenticate pour une autre coutume. entête. Je ne crois pas pourquoi les différents navigateurs ne peuvent pas le supporter. Dans quelques versions de Firefox, nous pouvons faire la requête xhr avec mozBackgroundRequest, mais dans les autres navigateurs ?? ici, il existe un lien intéressant link avec ce numéro en Chrome.

2
Kalamarico

Dans Mozilla Land, définir le paramètre mozBackgroundRequest de XMLHttpRequest ( docs ) sur true supprime ces boîtes de dialogue et entraîne simplement l'échec des demandes. Cependant, je ne sais pas quelle est la qualité de la prise en charge inter-navigateurs (notamment si la qualité des informations d'erreur sur ces demandes ayant échoué est très bonne sur tous les navigateurs.)

2
rakslice

J'ai le même problème avec MVC 5 et VPN où chaque fois que nous sommes en dehors de la DMZ en utilisant le VPN, nous nous trouvons dans l'obligation de répondre à ce message du navigateur. En utilisant .net je gère simplement le routage de l'erreur en utilisant

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

jusqu'à présent, cela a fonctionné, car l'action Index sous le contrôleur d'origine valide l'utilisateur. Si cette connexion échoue, la vue de cette action contient des contrôles de connexion que j'utilise pour connecter l'utilisateur à l'aide de la requête LDAP transmise aux services d'annuaire:

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

Bien que cela ait fonctionné jusqu'à présent, et je dois vous dire que je le teste toujours et que le code ci-dessus n'a pas de raison de s'exécuter, il est donc sujet à suppression. Les tests incluent actuellement la découverte d'un cas où du code n'est plus utile. Encore une fois, il s’agit d’un travail en cours, mais comme cela pourrait vous aider ou stimuler votre cerveau pour quelques idées, j’ai décidé de l’ajouter maintenant ... Je le mettrai à jour avec les résultats finaux une fois tous les tests terminés.

1
Clarence

J'utilise Node, Express & Passport et je me débattais avec le même problème. Je l'ai obtenu en définissant explicitement l'en-tête www-authenticate sur une chaîne vide. Dans mon cas, cela ressemblait à ceci:

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

J'espère que cela aide quelqu'un!

0
John Knotts

Pour ceux qui utilisent C #, voici ActionAttribute qui renvoie 400 au lieu de 401 et le dialogue d'authentification de base 'swallows'.

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

utiliser comme suit:

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

J'espère que cela vous fait gagner du temps.

0