Domanda

La mia applicazione web ha una pagina di accesso che invia le credenziali di autenticazione tramite una chiamata AJAX.Se l'utente inserisce nome utente e password corretti, va tutto bene, altrimenti accade quanto segue:

  1. Il server Web determina che, sebbene la richiesta includa un'intestazione di autorizzazione ben formata, le credenziali nell'intestazione non vengono autenticate correttamente.
  2. Il server Web restituisce un codice di stato 401 e include una o più intestazioni WWW-Authenticate che elencano i tipi di autenticazione supportati.
  3. Il browser rileva che la risposta alla mia chiamata sull'oggetto XMLHttpRequest è un 401 e la risposta include le intestazioni WWW-Authenticate.Quindi viene visualizzata una finestra di dialogo di autenticazione che richiede, ancora una volta, il nome utente e la password.

Va tutto bene fino al passaggio 3.Non voglio che venga visualizzata la finestra di dialogo, voglio gestire la risposta 401 nella mia funzione di callback AJAX.(Ad esempio, visualizzando un messaggio di errore nella pagina di accesso.) Voglio che l'utente reinserisca il nome utente e la password, ovviamente, ma voglio che vedano il mio modulo di accesso amichevole e rassicurante, non quello brutto e predefinito del browser finestra di dialogo di autenticazione.

Per inciso, non ho alcun controllo sul server, quindi far sì che restituisca un codice di stato personalizzato (ovvero qualcosa di diverso da 401) non è un'opzione.

Esiste un modo per sopprimere la finestra di dialogo di autenticazione?In particolare, posso eliminare la finestra di dialogo Autenticazione richiesta in Firefox 2 o versioni successive?Esiste un modo per sopprimere Connect to [ospite] dialogo in IE 6 e versioni successive?


Modificare
Ulteriori informazioni dall'autore (settembre)18):
Dovrei aggiungere che il vero problema con la finestra di dialogo di autenticazione del browser che appare è che fornisce informazioni insufficienti all'utente.

L'utente ha appena inserito un nome utente e una password tramite il modulo nella pagina di accesso, crede di averli digitati entrambi correttamente e di aver fatto clic sul pulsante di invio o di aver premuto invio.La sua aspettativa è che verrà portato alla pagina successiva o forse gli verrà detto che ha inserito le informazioni in modo errato e che dovrebbe riprovare.Tuttavia, gli viene invece presentata una finestra di dialogo inaspettata.

Il dialogo non riconosce il fatto che ha appena fatto inserire un nome utente e una password.Non afferma chiaramente che si è verificato un problema e che dovrebbe riprovare.Invece, la finestra di dialogo presenta all'utente informazioni criptiche come "Il sito dice:'[regno]'." Dove [regno] è un nome di regno breve che solo un programmatore potrebbe amare.

I progettisti di browser Web prendono nota:nessuno si chiederebbe come sopprimere la finestra di dialogo di autenticazione se la finestra di dialogo stessa fosse semplicemente più user-friendly.IL intero Il motivo per cui sto creando un modulo di accesso è che il nostro team di gestione del prodotto considera giustamente orribili le finestre di dialogo di autenticazione dei browser.

È stato utile?

Soluzione

Non penso che ciò sia possibile: se usi l'implementazione del client HTTP del browser, verrà sempre visualizzata quella finestra di dialogo.Mi vengono in mente due hack:

  1. Forse Flash lo gestisce in modo diverso (non ho ancora provato), quindi avere un filmato flash per effettuare la richiesta potrebbe essere d'aiuto.

  2. Puoi impostare un "proxie" per il servizio a cui stai accedendo sul tuo server e fare in modo che modifichi leggermente le intestazioni di autenticazione, in modo che il browser non le riconosca.

Altri suggerimenti

Ho riscontrato lo stesso problema qui e l'ingegnere di backend della mia azienda ha implementato un comportamento che apparentemente è considerato una buona pratica:quando una chiamata a un URL restituisce un 401, se il client ha impostato l'intestazione X-Requested-With: XMLHttpRequest, il server elimina il file www-authenticate intestazione nella sua risposta.

L'effetto collaterale è che il popup di autenticazione predefinito non viene visualizzato.

Assicurati che la tua chiamata API abbia l'estensione X-Requested-With intestazione impostata su XMLHttpRequest.In tal caso non c'è altro da fare se non modificare il comportamento del server secondo questa buona pratica...

Il browser visualizza una richiesta di accesso quando sono soddisfatte entrambe le seguenti condizioni:

  1. Lo stato HTTP è 4xx
  2. WWW-Authenticate l'intestazione è presente nella risposta

Se puoi controllare la risposta HTTP, puoi rimuovere il file WWW-Authenticate dalla risposta e il browser non visualizzerà la finestra di dialogo di accesso.

Se non puoi controllare la risposta, puoi impostare un proxy per filtrare i file WWW-Authenticate intestazione dalla risposta.

Per quanto ne so (sentitevi liberi di correggermi se sbaglio), non c'è modo di impedire la richiesta di accesso una volta che il browser riceve il messaggio WWW-Authenticate intestazione.

Mi rendo conto che questa domanda e le sue risposte sono molto antiche.Ma sono finito qui.Forse lo faranno anche gli altri.

Se hai accesso al codice per il servizio web che restituisce il file 401.Cambia semplicemente il servizio per restituire un 403 (Proibito) in questa situazione invece di 401.Il browser non richiederà le credenziali in risposta a un 403.403 è il codice corretto per un utente autenticato che non è autorizzato per una risorsa specifica.Questa sembra essere la situazione dell'OP.

Dal documento IETF su 403:

Un server che riceve credenziali valide che non sono adeguate per ottenere l'accesso dovrebbe rispondere con il codice di stato 403 (proibito)

In Mozilla puoi ottenerlo con il seguente script quando crei l'oggetto XMLHttpRequest:

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

La 2a riga impedisce la finestra di dialogo....

Quale tecnologia server utilizzi ed esiste un prodotto particolare che utilizzi per l'autenticazione?

Dato che il browser sta solo facendo il suo lavoro, credo che tu debba cambiare le cose sul lato server per non restituire un codice di stato 401.Ciò potrebbe essere fatto utilizzando moduli di autenticazione personalizzati che restituiscono semplicemente nuovamente il modulo quando l'autenticazione fallisce.

In Mozilla land, impostando il parametro mozBackgroundRequest di XMLHttpRequest (documenti) su true sopprime tali finestre di dialogo e fa sì che le richieste semplicemente falliscano.Tuttavia, non so quanto sia valido il supporto multibrowser (incluso se la qualità delle informazioni sugli errori su tali richieste non riuscite sia molto buona tra i browser).

jan.vdbergh ha la verità, se puoi cambiare il 401 sul lato server con un altro codice di stato, il browser non catturerà e non disegnerà il pop-up.Un'altra soluzione potrebbe essere quella di modificare l'intestazione WWW-Authenticate con un'altra intestazione personalizzata.Non credo perché i diversi browser non possano supportarlo, in alcune versioni di Firefox possiamo eseguire la richiesta xhr con mozBackgroundRequest, ma negli altri browser??ecco, c'è un interessante collegamento con questo problema in Chromium.

Ho lo stesso problema con MVC 5 e VPN in cui ogni volta che siamo fuori dalla DMZ utilizzando la VPN, ci troviamo a dover rispondere a questo messaggio del browser.Utilizzando .net gestisco semplicemente il routing dell'errore utilizzando

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

finora ha funzionato perché l'azione Index sotto il controller home convalida l'utente.La vista in questa azione, se l'accesso non ha esito positivo, dispone di controlli di accesso che utilizzo per accedere all'utente utilizzando la query LDAP trasmessa ai servizi di directory:

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

Anche se finora ha funzionato bene, devo farti sapere che lo sto ancora testando e il codice sopra non ha motivo di essere eseguito, quindi è soggetto a rimozione...i test attualmente includono il tentativo di scoprire un caso in cui il secondo set di codice sia più utile.Ancora una volta, questo è un lavoro in corso, ma poiché potrebbe esserti di aiuto o stimolarti la mente con alcune idee, ho deciso di aggiungerlo ora...Lo aggiornerò con i risultati finali una volta terminati tutti i test.

Per coloro che non cantano C# ecco ActionAttribute che ritorna 400 invece di 401, e "ingoia" la finestra di dialogo di autenticazione di base.

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

utilizzare come segue:

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

Spero che questo ti faccia risparmiare un po' di tempo.

Sto utilizzando Node, Express e Passport e stavo lottando con lo stesso problema.L'ho fatto funzionare impostando esplicitamente il file www-authenticate intestazione in una stringa vuota.Nel mio caso, assomigliava a questo:

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

Spero che questo aiuti qualcuno!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top