Question

Mon application Web possède 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 sinon, les événements suivants se produisent:

  1. Le serveur Web détermine que, bien que la demande inclue 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. Une boîte de dialogue d'authentification s'ouvre, vous 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éplacé, par défaut. dialogue d'authentification.

Incidemment, je n’ai aucun contrôle sur le serveur. Il n’est donc pas possible de lui renvoyer un code d’état personnalisé (c’est-à-dire autre chose qu’un 401).

Existe-t-il un moyen 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 septembre):
Je devrais ajouter que le vrai problème avec la boîte de dialogue d’authentification du navigateur qui s’ouvre est qu’elle 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 vient d'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ù [domaine] 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 raison entière 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 terribles.

Était-ce utile?

La solution

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 s'affichera toujours. Deux hacks me 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 un "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, afin que le navigateur ne les reconnaisse pas.

Autres conseils

J'ai rencontré le même problème ici, et l'ingénieur principal de mon entreprise a mis en œuvre un comportement qui est apparemment considéré comme une bonne pratique: lorsqu'un appel à une URL renvoie un 401, si le client a défini l'en-tête X- Demandé avec: 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 de votre appel d'API est défini sur XMLHttpRequest . Si c'est le cas, il n'y a rien d'autre à faire que de changer le comportement du serveur conformément à cette bonne pratique ...

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

  1. l'état HTTP est 4xx
  2. L'en-tête
  3. WWW-Authenticate est présent dans la réponse

Si vous pouvez contrôler la réponse HTTP, vous pouvez 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'y a aucun moyen d'empêcher l'invite de connexion une fois que le navigateur a reçu l'en-tête WWW-Authenticate .

Je réalise que cette question et ses réponses sont très anciennes. Mais j'ai fini ici. Peut-être que d’autres aussi.

Si vous avez accès au code du service Web renvoyant le numéro 401. Modifiez simplement le service pour qu'il retourne 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 message 403. 403 est le code correct pour un utilisateur authentifié qui n'est pas autorisé pour une ressource spécifique. Ce qui semble être la situation du PO.

Extrait du document IETF sur 403:

Un serveur qui reçoit des informations d'identification valides qui ne permettent pas    accéder doit répondre avec le code de statut 403 (Interdit)

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 deuxième ligne empêche la boîte de dialogue ....

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 modifier le serveur pour ne pas renvoyer un code d'état 401. Pour ce faire, vous pouvez utiliser des formulaires d’authentification personnalisés qui renvoient simplement le formulaire lorsque l’authentification échoue.

Dans Mozilla Land, définition du paramètre mozBackgroundRequest de XMLHttpRequest ( docs ) à true supprime ces dialogues et provoque simplement l'échec des requêtes. 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.)

jan.vdbergh a la vérité: si vous pouvez remplacer le code 401 du côté du serveur par un autre code d'état, le navigateur ne détectera ni ne masquera la fenêtre contextuelle. Une autre solution pourrait être de changer l'en-tête WWW-Authenticate pour un autre en-tête personnalisé. 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 y a un intéressant lien avec ce problème dans Chromium.

J'ai le même problème avec MVC 5 et VPN où, chaque fois que nous nous trouvons en dehors de la zone démilitarisée 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");

Même si cela a bien fonctionné jusqu'à présent, je dois vous faire savoir que je le teste toujours et que le code ci-dessus n'a aucune raison de s'exécuter. Il peut donc être supprimé. Les tests incluent actuellement la recherche d'un cas où le second jeu de code est plus utile. Encore une fois, c’est un travail en cours, mais comme cela pourrait vous aider ou vous aider à trouver des 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.

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

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 fera gagner du temps.

J'utilise Node, Express & amp; Passeport et luttait 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!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top