it-swarm-eu.dev

Jak mohu potlačit ověřovací dialog prohlížeče?

Moje webová aplikace má přihlašovací stránku, která odesílá ověřovací pověření prostřednictvím volání AJAX. Pokud uživatel zadá správné uživatelské jméno a heslo, je vše v pořádku, ale pokud ne, stane se následující:

  1. Webový server určuje, že ačkoli požadavek zahrnoval dobře vytvořenou hlavičku autorizace, pověření v záhlaví se úspěšně neoverují.
  2. Webový server vrací stavový kód 401 a obsahuje jeden nebo více záhlaví WWW-Authenticate, ve kterých jsou uvedeny podporované typy ověřování.
  3. Prohlížeč zjistí, že odpověď na mé volání v objektu XMLHttpRequest je 401 a odpověď obsahuje záhlaví WWW-Authenticate. Poté se zobrazí dialogové okno s ověřením, v němž se znovu zeptá na uživatelské jméno a heslo.

To je vše v pořádku až do kroku 3. Nechci, aby se dialog vyskočil, chci se zabývat odpovědí 401 v mé funkci zpětného volání AJAX. (Například zobrazením chybové zprávy na přihlašovací stránce.) Chci, aby uživatel znovu zadal své uživatelské jméno a heslo, samozřejmě, ale chci, aby viděli můj přátelský, uklidňující přihlašovací formulář, ne ošklivý prohlížeč. ověřování.

Mimochodem, nemám žádnou kontrolu nad serverem, takže po návratu vlastního stavového kódu (tj. Něco jiného než 401) není možnost.

Existuje nějaký způsob, jak mohu potlačit ověřovací dialog? Mohu v dialogovém okně Firefox 2 nebo novějším potlačit dialog Požadované ověření? Existuje nějaký způsob, jak potlačit dialogové okno Connect to [Host] / v IE 6 a novější?


Upravit
Další informace od autora (18. září):
Měla bych dodat, že skutečným problémem v dialogovém okně ověřování prohlížeče je, že uživateli neposkytuje dostatečné informace.

Uživatel právě zadal uživatelské jméno a heslo prostřednictvím formuláře na přihlašovací stránce, věří, že je zadal správně, a klikl na tlačítko Odeslat nebo stiskl klávesu Enter. Jeho očekávání spočívá v tom, že bude převezen na další stránku, nebo možná řekne, že své údaje zadal nesprávně a měl by to zkusit znovu. Je však místo toho předložen neočekávané dialogové okno.

Dialog neuznává, že právě udělal zadejte uživatelské jméno a heslo. To jasně neříká, že tam byl problém a že on by měl zkusit to znovu. Místo toho dialogové okno představuje uživatele s kryptografickými informacemi, jako např. „Místo říká: ' [realm] '. Kde [realm] je krátký název oblasti, který by mohl milovat pouze programátor.

Návrháři webových broswerů berou na vědomí: nikdo by se nezeptal, jak potlačit dialog pro ověření, pokud by samotný dialog byl jednodušší pro uživatele. celý důvod, proč dělám přihlašovací formulář, je, že náš tým pro správu produktů správně považuje dialogy ověřování prohlížečů za hrozné.

72
dgvid

Nemyslím si, že je to možné - pokud používáte implementaci HTTP klienta v prohlížeči, vždy se objeví dialog. Na mysl přijdou dva hacky:

  1. Možná, že to Flash zpracovává jinak (ještě jsem to nezkusil), takže s flash filmem může tento požadavek pomoci.

  2. Můžete nastavit 'proxie' pro službu, ke které přistupujete na svém vlastním serveru, a nechat ji trochu změnit, aby prohlížeč nerozpoznal.

17
Marijn

Setkal jsem se zde se stejným problémem, a backend inženýr v mé společnosti implementoval chování, které je zřejmě považováno za dobrou praxi: když volání na URL vrátí 401, pokud klient nastavil hlavičku X-Requested-With: XMLHttpRequest, server upustí hlavičku www-authenticate ve své odpovědi. 

Vedlejším efektem je, že se nezobrazí výchozí vyskakovací okno.

Ujistěte se, že volání API má záhlaví X-Requested-With nastaveno na XMLHttpRequest. Pokud ano, není nic jiného, ​​než změnit chování serveru podle tohoto osvědčeného postupu ...

44

Prohlížeč zobrazí přihlašovací údaje Prompt, když jsou splněny obě následující podmínky:

  1. Stav HTTP je 4xx
  2. WWW-Authenticate záhlaví je přítomno v odpovědi

Pokud můžete ovládat odpověď HTTP, můžete z odpovědi odebrat záhlaví WWW-Authenticate a prohlížeč neotevře přihlašovací dialog.

Pokud odpověď nemůžete ovládat, můžete nastavit proxy pro filtrování záhlaví WWW-Authenticate z odpovědi.

Pokud vím (neváhejte a opravte mě, pokud se mýlím), neexistuje způsob, jak zabránit přihlašovací výzvě, jakmile prohlížeč obdrží záhlaví WWW-Authenticate.

14
rustyx

Uvědomuji si, že tato otázka a její odpovědi jsou velmi staré. Ale skončil jsem tady. Možná i ostatní.

Pokud máte přístup k kódu pro webovou službu, která vrací 401. Stačí změnit službu vrátit 403 (zakázáno) v této situaci místo 401. Prohlížeč nebude výzva k zadání pověření v reakci na 403. 403 je správný kód pro ověřeného uživatele, který není autorizován pro konkrétní prostředek. Což se jeví jako situace OP.

Z dokumentu IETF na 403:

Server, který obdrží platná pověření, která nejsou dostatečná k přístupu , By měl reagovat se stavovým kódem 403 (Zakázáno)

5
Jim Reineri

Při vytváření objektu XMLHttpRequest můžete v Mozille dosáhnout následujícím skriptem:

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

Druhý řádek zabraňuje dialogovému oknu.

4
Yogesh

Jakou serverovou technologii používáte a je k dispozici určitý produkt, který používáte pro ověřování?

Vzhledem k tomu, že prohlížeč dělá svou práci, věřím, že na straně serveru musíte změnit věci, abyste nevrátili kód stavu 401. To lze provést pomocí vlastních formulářů ověřování, které jednoduše vrátí formulář znovu při selhání ověřování.

3
jan.vdbergh

jan.vdbergh má pravdu, pokud můžete změnit 401 na straně serveru pro další stavový kód, prohlížeč nebude zachytávat a malovat vyskakovací okno. Dalším řešením by bylo změnit záhlaví WWW-Authenticate pro další vlastní záhlaví. Nevěřím, proč to jiný prohlížeč nemůže podporovat, v několika verzích Firefoxu můžeme provést požadavek xhr s mozBackgroundRequest, ale v ostatních prohlížečích? zde je zajímavý odkaz s tímto problémem v Chromu.

2
Kalamarico

V zemi Mozilla nastavení parametru mozBackgroundRequest XMLHttpRequest ( docs ) na true potlačí tato dialogová okna a způsobí selhání požadavků. Nevím však, jak dobrá je podpora přes internetový prohlížeč (včetně toho, zda je kvalita chybových informací o těchto neúspěšných požadavcích v prohlížečích velmi dobrá).

2
rakslice

Mám stejný problém s MVC 5 a VPN, kde kdykoliv jsme mimo DMZ pomocí VPN, zjistíme, že musíme odpovědět na tuto zprávu prohlížeče. Pomocí .net I jednoduše zpracovat směrování chyby pomocí

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

doposud to fungovalo, protože akce indexu pod domovským řadičem ověřuje uživatele. Zobrazení v této akci, pokud je přihlášení neúspěšné, obsahuje ovládací prvky přihlášení, které používám k přihlášení uživatele pomocí dotazu LDAP předaného do služby Directory Services:

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

I když to doposud fungovalo dobře a musím vám oznámit, že jsem to stále testoval a výše uvedený kód neměl žádný důvod k běhu, takže podléhá odstranění ... testování v současné době zahrnuje pokus o zjištění případu, kdy druhá sada použití kódu. Opět platí, že se jedná o nedokončenou práci, ale protože by to mohlo být nějaká pomoc, nebo si mozek pro některé nápady, rozhodl jsem se přidat ji teď ... Budu aktualizovat s konečnými výsledky po dokončení všech testů.

1
Clarence

Používám Node, Express & Passport a bojoval jsem se stejným problémem. Dostal jsem ho do práce tak, že jsem explicitně nastavil hlavičku www-authenticate na prázdný řetězec. V mém případě to vypadalo takto:

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

Doufám, že to někomu pomůže!

0
John Knotts

Pro ty, kteří odjíždějí C # zde je ActionAttribute, které vrací 400 místo 401, a 'swallows' Basic dialogového okna.

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

použít jako následující:

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

Doufám, že vám to ušetří nějaký čas.

0