it-swarm.it

Come posso sopprimere la finestra di autenticazione del browser?

La mia applicazione Web ha una pagina di accesso che invia le credenziali di autenticazione tramite una chiamata AJAX. Se l'utente immette il nome utente e la password corretti, tutto va bene, ma in caso contrario, accade quanto segue:

  1. Il server Web determina che sebbene la richiesta includesse un'intestazione Autorizzazione ben formata, le credenziali nell'intestazione non si autenticano correttamente.
  2. Il server Web restituisce un codice di stato 401 e include una o più intestazioni Autenticazione WWW che elencano i tipi di autenticazione supportati.
  3. Il browser rileva che la risposta alla mia chiamata sull'oggetto XMLHttpRequest è una 401 e la risposta include intestazioni Autenticazione WWW. Viene quindi visualizzata una finestra di autenticazione che richiede, nuovamente, nome utente e password.

Tutto ciò va bene fino al passaggio 3. Non voglio che la finestra di dialogo compaia, 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 amichevole, rassicurante modulo di login, non il brutto browser, predefinito finestra di autenticazione.

Per inciso, non ho alcun controllo sul server, quindi averlo restituire un codice di stato personalizzato (ad esempio, qualcosa di diverso da un 401) non è un'opzione.

C'è un modo per sopprimere la finestra di autenticazione? In particolare, posso sopprimere la finestra di dialogo Richiesta di autenticazione in Firefox 2 o versioni successive? C'è un modo per sopprimere la finestra di dialogo Connetti a [Host] in IE 6 e versioni successive?


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

L'utente ha appena inserito un nome utente e una password tramite il modulo nella pagina di accesso, ritiene di averli digitati entrambi correttamente e ha fatto clic sul pulsante Invia o su Invio. La sua aspettativa è che sarà portato alla pagina successiva o forse gli verrà detto che ha inserito le sue informazioni in modo errato e dovrebbe riprovare. Tuttavia, viene presentato con una finestra di dialogo inaspettata.

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

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

72
dgvid

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

  1. Forse Flash lo gestisce in modo diverso (non ho ancora provato), quindi avere un film in flash potrebbe rendere la richiesta utile.

  2. È possibile configurare un 'proxy' per il servizio a cui si sta accedendo sul proprio server e modificarlo un po ', in modo che il browser non li riconosca.

17
Marijn

Ho riscontrato lo stesso problema qui e l'ingegnere di backend della mia azienda ha implementato un comportamento 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 rilascia l'intestazione www-authenticate nella sua risposta. 

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

Assicurati che la tua chiamata API abbia l'intestazione X-Requested-With impostata su XMLHttpRequest. Se è così, non c'è niente da fare se non cambiare il comportamento del server in base a questa buona pratica ...

Il browser visualizza un prompt di accesso quando sono soddisfatte entrambe le seguenti condizioni:

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

Se è possibile controllare la risposta HTTP, è possibile rimuovere l'intestazione WWW-Authenticate dalla risposta e il browser non farà apparire la finestra di dialogo di accesso.

Se non riesci a controllare la risposta, puoi impostare un proxy per filtrare l'intestazione WWW-Authenticate dalla risposta.

Per quanto ne so (sentiti libero di correggermi se ho torto), non c'è modo di impedire il prompt di accesso una volta che il browser riceve l'intestazione WWW-Authenticate.

14
rustyx

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

Se si ha accesso al codice per il servizio Web che restituisce il 401. Basta cambiare il servizio per restituire un 403 (Proibito) in questa situazione invece 401. Il browser non chiederà le credenziali in risposta a un 403. 403 è il codice corretto per un utente autenticato che non è autorizzato per una risorsa specifica. Quale sembra essere la situazione del PO.

Dal documento IETF su 403:

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

5
Jim Reineri

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 seconda linea impedisce la finestra di dialogo ....

4
Yogesh

Quale tecnologia server usi e c'è un particolare prodotto che usi per l'autenticazione?

Dal momento che il browser sta facendo il suo lavoro, credo che sia necessario modificare le cose sul lato server per non restituire un codice di stato 401. Questo potrebbe essere fatto utilizzando moduli di autenticazione personalizzati che restituiscono semplicemente il modulo nuovamente quando l'autenticazione fallisce.

3
jan.vdbergh

jan.vdbergh ha la verità, se è possibile modificare il 401 sul lato server per un altro codice di stato, il browser non catturerà e Paint il pop-up . Un'altra soluzione potrebbe essere cambiare l'intestazione WWW-Authenticate per un'altra custom intestazione. Non credo perché il diverso browser non può supportarlo, in alcune versioni di Firefox possiamo fare la richiesta xhr con mozBackgroundRequest, ma negli altri browser ?? qui, c'è un interessante link con questo problema in Chromium.

2
Kalamarico

In Mozilla land, l'impostazione del parametro mozBackgroundRequest di XMLHttpRequest ( docs ) su true elimina le finestre di dialogo e causa semplicemente il fallimento delle richieste. Tuttavia, non so quanto sia valido il supporto cross-browser (incluso se la qualità delle informazioni di errore su quelle richieste non riuscite è molto buona tra i vari browser.)

2
rakslice

Ho lo stesso problema con MVC 5 e VPN, dove ogni volta che ci troviamo al di fuori del DMZ utilizzando la VPN, ci troviamo a dover rispondere a questo messaggio del browser. Usando .net Semplicemente gestisco il routing dell'errore usando

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

finora ha funzionato perché l'azione Index sotto il controller di casa convalida l'utente. La vista in questa azione, se l'accesso non è riuscito, dispone di controlli di accesso che utilizzo per registrare l'utente utilizzando la query LDAP passata in Directory Services:

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

Anche se questo ha funzionato fino ad ora, e devo informarti che sto ancora testandolo e il codice sopra non ha avuto motivo di correre quindi è soggetto alla rimozione ... il testing include attualmente il tentativo di scoprire un caso in cui il secondo set di codice è di ulteriore utilità. Anche in questo caso, si tratta di un work in progress, ma dal momento che potrebbe essere di qualche aiuto o far correre il cervello per alcune idee, ho deciso di aggiungerlo ora ... Lo aggiornerò con i risultati finali una volta che tutti i test sono stati eseguiti.

1
Clarence

Sto usando Node, Express e Passport e stavo lottando con lo stesso problema. Ho funzionato impostando esplicitamente l'intestazione www-authenticate su 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 aiuti qualcuno!

0
John Knotts

Per chi non ha C # ecco qui ActionAttribute che restituisce 400 invece di 401 e 'swallows' nella 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);
    }
}

usare come segue:

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

Spero che questo ti salvi un po 'di tempo.

0