it-swarm-eu.dev

Wie kann ich den Authentifizierungsdialog des Browsers unterdrücken?

Meine Webanwendung verfügt über eine Anmeldeseite, auf der Authentifizierungsinformationen über einen Aufruf von AJAX übermittelt werden. Wenn der Benutzer den richtigen Benutzernamen und das richtige Kennwort eingibt, ist alles in Ordnung, aber wenn nicht, geschieht Folgendes:

  1. Der Webserver stellt fest, dass die Berechtigungsnachweise im Header nicht erfolgreich authentifiziert wurden, obwohl die Anforderung einen gut formatierten Berechtigungsheader enthielt.
  2. Der Webserver gibt einen 401-Statuscode zurück und enthält einen oder mehrere WWW-Authenticate-Header, die die unterstützten Authentifizierungstypen auflisten.
  3. Der Browser erkennt, dass die Antwort auf meinen Aufruf für das XMLHttpRequest-Objekt eine 401 ist, und die Antwort enthält WWW-Authenticate-Header. Daraufhin wird ein Authentifizierungsdialogfeld angezeigt, in dem Sie erneut nach Benutzername und Kennwort gefragt werden.

Dies ist bis Schritt 3 in Ordnung. Ich möchte nicht, dass das Dialogfeld angezeigt wird. Ich möchte die 401-Antwort in meiner AJAX - Rückruffunktion behandeln. (Zum Beispiel durch Anzeigen einer Fehlermeldung auf der Anmeldeseite.) Ich möchte, dass der Benutzer seinen Benutzernamen und sein Kennwort natürlich erneut eingibt, aber er möchte, dass mein freundliches, beruhigendes Anmeldeformular und nicht der hässliche Standard des Browsers angezeigt wird Authentifizierungsdialog.

Im Übrigen habe ich keine Kontrolle über den Server, daher ist es nicht möglich, einen benutzerdefinierten Statuscode (d. H. Etwas anderes als 401) zurückzugeben.

Gibt es eine Möglichkeit, den Authentifizierungsdialog zu unterdrücken? Kann ich insbesondere das Dialogfeld "Authentifizierung erforderlich" in Firefox 2 oder höher unterdrücken? Gibt es eine Möglichkeit, den Dialog Verbinden mit [Host] in IE 6 und höher zu unterdrücken?


Bearbeiten
Zusätzliche Angaben des Autors (18. September):
Ich sollte hinzufügen, dass das eigentliche Problem beim Auftauchen des Authentifizierungsdialogfelds des Browsers darin besteht, dass der Benutzer nicht genügend Informationen erhält.

Der Benutzer hat gerade einen Benutzernamen und ein Kennwort über das Formular auf der Anmeldeseite eingegeben. Er glaubt, dass er beide korrekt eingegeben hat, und er hat auf die Schaltfläche "Senden" geklickt oder die Eingabetaste gedrückt. Er geht davon aus, dass er auf die nächste Seite weitergeleitet wird oder vielleicht gesagt wird, dass er seine Informationen falsch eingegeben hat und es erneut versuchen sollte. Stattdessen wird jedoch ein unerwartetes Dialogfeld angezeigt.

Der Dialog bestätigt nicht die Tatsache, dass er did einen Benutzernamen und ein Kennwort eingibt. Es heißt nicht eindeutig, dass es ein Problem gab und dass er es erneut versuchen sollte. Stattdessen zeigt das Dialogfeld dem Benutzer kryptische Informationen wie "Die Site sagt: '(Realm)'" an. Dabei ist [Realm] ein kurzer Realm-Name, den nur ein Programmierer lieben könnte.

Webbrowser-Designer nehmen zur Kenntnis: Niemand würde fragen, wie er den Authentifizierungsdialog unterdrücken kann, wenn der Dialog selbst benutzerfreundlicher wäre. Der gesamte Grund, warum ich ein Anmeldeformular mache, ist, dass unser Produktmanagementteam die Authentifizierungsdialogfelder der Browser zu Recht für schrecklich hält.

72
dgvid

Ich glaube nicht, dass dies möglich ist - wenn Sie die HTTP-Client-Implementierung des Browsers verwenden, wird dieses Dialogfeld immer angezeigt. Zwei Hacks kommen mir in den Sinn:

  1. Möglicherweise behandelt Flash dies anders (ich habe es noch nicht versucht), daher könnte es hilfreich sein, wenn ein Flash-Film die Anfrage macht.

  2. Sie können einen 'Proxy' für den Dienst einrichten, auf den Sie auf Ihrem eigenen Server zugreifen, und die Authentifizierungsheader ein wenig ändern, sodass der Browser sie nicht erkennt.

17
Marijn

Ich bin hier auf das gleiche Problem gestoßen, und der Backend-Ingenieur in meinem Unternehmen hat ein Verhalten implementiert, das anscheinend als eine bewährte Methode gilt: Wenn ein Aufruf einer URL eine 401 zurückgibt, wenn der Client den Header X-Requested-With: XMLHttpRequest gesetzt hat, löscht der Server den Header www-authenticate in seiner Antwort. 

Der Nebeneffekt ist, dass das Standard-Popup für die Authentifizierung nicht angezeigt wird.

Stellen Sie sicher, dass für den API-Aufruf der X-Requested-With-Header auf XMLHttpRequest gesetzt ist. In diesem Fall gibt es nichts zu tun, außer das Serververhalten entsprechend dieser bewährten Methode zu ändern ...

Der Browser zeigt eine Anmeldeaufforderung an, wenn beide der folgenden Bedingungen erfüllt sind:

  1. Der HTTP-Status ist 4xx
  2. WWW-Authenticate-Header ist in der Antwort vorhanden

Wenn Sie die HTTP-Antwort steuern können, können Sie den WWW-Authenticate-Header aus der Antwort entfernen, und der Browser öffnet den Anmeldedialog nicht.

Wenn Sie die Antwort nicht steuern können, können Sie einen Proxy einrichten, um den WWW-Authenticate-Header aus der Antwort herauszufiltern.

Soweit ich weiß (korrigieren Sie mich bitte, wenn ich falsch liege), gibt es keine Möglichkeit, die Anmeldeaufforderung zu verhindern, sobald der Browser den WWW-Authenticate-Header erhält.

14
rustyx

Mir ist klar, dass diese Frage und ihre Antworten sehr alt sind. Aber ich bin hier gelandet. Vielleicht tun es auch andere.

Wenn Sie Zugriff auf den Code für den Webdienst haben, der die 401 zurückgibt. Ändern Sie einfach den Dienst, um stattdessen eine 403 (Verboten) zurückzugeben. Stattdessen fordert der Browser keine Anmeldeinformationen auf richtiger Code für einen authentifizierten Benutzer, der nicht für eine bestimmte Ressource autorisiert ist. Welches scheint die Situation des OP zu sein.

Aus dem IETF-Dokument auf 403:

Ein Server, der gültige Anmeldeinformationen erhält, die nicht für .__ geeignet sind. Zugang erhalten sollte mit dem Statuscode 403 (Forbidden) antworten

5
Jim Reineri

In Mozilla können Sie dies mit dem folgenden Skript erreichen, wenn Sie das XMLHttpRequest-Objekt erstellen:

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

Die 2. Zeile verhindert das Dialogfeld ....

4
Yogesh

Welche Servertechnologie verwenden Sie und gibt es ein bestimmtes Produkt, das Sie zur Authentifizierung verwenden?

Da der Browser nur seine Arbeit erledigt, müssen Sie auf der Serverseite Änderungen vornehmen, damit kein 401-Statuscode zurückgegeben wird. Dies kann mithilfe von benutzerdefinierten Authentifizierungsformularen erfolgen, die das Formular einfach zurückgeben, wenn die Authentifizierung fehlschlägt.

3
jan.vdbergh

jan.vdbergh hat die Wahrheit, wenn Sie die 401 auf Serverseite für einen anderen Statuscode ändern können, fängt der Browser das Paint-Popup-Fenster nicht ab und malt das Popup .. __ Header. Ich glaube nicht, warum der andere Browser es nicht unterstützen kann. In einigen Versionen von Firefox können wir die xhr-Anfrage mit mozBackgroundRequest durchführen, aber in den anderen Browsern? hier gibt es ein interessantes link mit dieser Ausgabe in Chromium.

2
Kalamarico

Wenn Sie in Mozilla Land den Parameter mozBackgroundRequest von XMLHttpRequest ( docs ) auf true setzen, werden diese Dialoge unterdrückt, und die Anforderungen schlagen fehl. Ich weiß jedoch nicht, wie gut die Cross-Browser-Unterstützung ist (einschließlich der Frage, ob die Fehlerinformationen zu diesen fehlgeschlagenen Anforderungen in allen Browsern sehr gut sind.)

2
rakslice

Ich habe das gleiche Problem mit MVC 5 und VPN. Wenn wir uns außerhalb des DMZ befinden, müssen wir diese Browser-Nachricht beantworten. Mit .net gehe ich einfach mit dem Routing des Fehlers um

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

bisher hat es funktioniert, weil die Indexaktion unter dem Home-Controller den Benutzer validiert. Wenn die Anmeldung in dieser Aktion nicht erfolgreich ist, verfügt sie über Anmeldungssteuerelemente, die ich zum Anmelden des Benutzers mithilfe der LDAP-Abfrage verwendet, die an Directory Services übergeben wird:

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

Während dies bisher gut funktioniert hat und ich muss Ihnen mitteilen, dass ich es immer noch teste und der obige Code keinen Grund hatte, so zu laufen, dass er entfernt werden kann ... Das Testen umfasst derzeit den Versuch, einen Fall zu entdecken, bei dem der zweite Satz eingestellt ist Code ist mehr nützlich. Wieder ist dies eine Arbeit in Arbeit, aber da es von etwas Hilfe sein könnte oder Ihr Gehirn nach Ideen suchen könnte, entschied ich mich, es jetzt hinzuzufügen ... Ich werde es mit den endgültigen Ergebnissen aktualisieren, sobald alle Tests abgeschlossen sind.

1
Clarence

Ich benutze Node, Express & Passport und hatte mit dem gleichen Problem zu kämpfen. Ich habe es zum Laufen gebracht, indem ich den www-authenticate-Header explizit auf eine leere Zeichenfolge gesetzt habe. In meinem Fall sah es so aus:

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

Ich hoffe das hilft jemandem!

0
John Knotts

Für diejenigen, die C # verwenden, ist hier ActionAttribute, die 400 anstelle von 401 zurückgibt, und der grundlegende Auth-Dialog "schluckt".

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

verwenden Sie wie folgt:

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

Ich hoffe, das erspart Ihnen etwas Zeit.

0