Moja aplikacja internetowa ma stronę logowania, która przesyła dane uwierzytelniające za pośrednictwem wywołania AJAX. Jeśli użytkownik wprowadzi poprawną nazwę użytkownika i hasło, wszystko jest w porządku, ale jeśli nie, dzieje się tak:
- Serwer WWW stwierdza, że chociaż żądanie zawierało poprawnie sformułowany nagłówek Authorization, poświadczenia w nagłówku nie są pomyślnie uwierzytelniane.
- Serwer sieciowy zwraca kod stanu 401 i zawiera jeden lub więcej nagłówków WWW-Authenticate wymieniających obsługiwane typy uwierzytelniania.
- Przeglądarka wykrywa, że odpowiedź na moje wywołanie obiektu XMLHttpRequest to 401, a odpowiedź zawiera nagłówki WWW-Authenticate. Następnie pojawia się okno dialogowe uwierzytelniania z pytaniem o nazwę użytkownika i hasło.
Do kroku 3 wszystko jest w porządku. Nie chcę, aby pojawiło się okno dialogowe, chcę obsłużyć odpowiedź 401 w mojej funkcji wywołania zwrotnego AJAX. (Na przykład wyświetlając komunikat o błędzie na stronie logowania). Oczywiście chcę, aby użytkownik ponownie wprowadził swoją nazwę użytkownika i hasło, ale chcę, aby zobaczył mój przyjazny, uspokajający formularz logowania, a nie brzydki, domyślny okno dialogowe uwierzytelniania.
Nawiasem mówiąc, nie mam kontroli nad serwerem, więc zwrócenie przez niego niestandardowego kodu stanu (tj. Czegoś innego niż 401) nie jest opcją.
Czy jest jakiś sposób, aby ukryć okno dialogowe uwierzytelniania? W szczególności, czy mogę pominąć okno dialogowe Wymagane uwierzytelnienie w przeglądarce Firefox 2 lub nowszej? Czy istnieje sposób na pominięcie okna dialogowego Połącz z [hostem] w przeglądarce IE 6 i nowszych?
Edytuj
Dodatkowe informacje od autora (18 września):
Powinienem dodać, że prawdziwym problemem z wyskakującym oknem dialogowym uwierzytelniania przeglądarki jest to, że podaje ono użytkownikowi niewystarczające informacje.
Użytkownik właśnie wprowadził nazwę użytkownika i hasło za pośrednictwem formularza na stronie logowania, uważa, że wpisał je poprawnie i kliknął przycisk przesyłania lub wcisnął Enter. Oczekuje, że zostanie przeniesiony na następną stronę lub może powiedziano mu, że wprowadził nieprawidłowe informacje i powinien spróbować ponownie. Jednak zamiast tego jest wyświetlane nieoczekiwane okno dialogowe.
Okno nie ma potwierdzenia faktu, że właśnie zrobił wprowadzić nazwę użytkownika i hasło. Nie stwierdza jasno, że wystąpił problem i że powinien spróbować ponownie. Zamiast tego okno dialogowe przedstawia użytkownikowi tajemnicze informacje, takie jak „Witryna mówi: ' [dziedzina] '”. Gdzie [dziedzina] to krótka nazwa dziedziny, którą może pokochać tylko programista.
Uwaga projektanci przeglądarek internetowych: nikt nie zapytałby, jak pominąć okno dialogowe uwierzytelniania, gdyby samo okno dialogowe było po prostu bardziej przyjazne dla użytkownika. Cały powód, że robię formularz logowania jest to, że nasz zespół zarządzania produktem słusznie uważa dialogi uwierzytelniania przeglądarek być okropne.
Odpowiedzi:
Nie sądzę, żeby to było możliwe - jeśli używasz implementacji klienta HTTP przeglądarki, zawsze pojawi się to okno dialogowe. Przychodzą mi na myśl dwa hacki:
Może Flash radzi sobie z tym inaczej (jeszcze nie próbowałem), więc posiadanie filmu flashowego sprawi, że żądanie może pomóc.
Możesz skonfigurować „serwer proxy” dla usługi, do której uzyskujesz dostęp na własnym serwerze, i poprosić go o nieco zmodyfikowanie nagłówków uwierzytelniania, aby przeglądarka ich nie rozpoznawała.
źródło
Napotkałem ten sam problem i inżynier zaplecza w mojej firmie zaimplementował zachowanie, które najwyraźniej jest uważane za dobrą praktykę: gdy wywołanie adresu URL zwraca 401, jeśli klient ustawił nagłówek
X-Requested-With: XMLHttpRequest
, serwer upuszczawww-authenticate
nagłówek w swoim odpowiedź.Efektem ubocznym jest to, że domyślne okienko uwierzytelniania nie jest wyświetlane.
Upewnij się, że wywołanie interfejsu API ma
X-Requested-With
nagłówek ustawiony naXMLHttpRequest
. Jeśli tak, nie pozostaje nic innego, jak zmienić zachowanie serwera zgodnie z tą dobrą praktyką ...źródło
DelegatingAuthenticationEntryPoint
obsługuje to zachowanie za Ciebie.Przeglądarka wyświetla monit logowania, gdy spełnione są oba poniższe warunki:
WWW-Authenticate
nagłówek jest obecny w odpowiedziJeśli możesz kontrolować odpowiedź HTTP, możesz usunąć
WWW-Authenticate
nagłówek z odpowiedzi, a przeglądarka nie wyświetli okna dialogowego logowania.Jeśli nie możesz kontrolować odpowiedzi, możesz skonfigurować serwer proxy, aby odfiltrować
WWW-Authenticate
nagłówek z odpowiedzi.O ile wiem (jeśli się mylę, nie wahaj się mnie poprawić), nie ma sposobu, aby zapobiec wyświetlaniu monitu o logowanie, gdy przeglądarka otrzyma
WWW-Authenticate
nagłówek.źródło
WWW-Authenticate
wartości nagłówka, patrz stackoverflow.com/a/1748451/225217Zdaję sobie sprawę, że to pytanie i odpowiedzi na nie są bardzo stare. Ale skończyłem tutaj. Być może inni też.
Jeśli masz dostęp do kodu usługi sieciowej, która zwraca 401. Po prostu zmień usługę, aby zwracała 403 (zabronione) w tej sytuacji zamiast 401. Przeglądarka nie będzie pytać o poświadczenia w odpowiedzi na 403. 403 to poprawny kod dla uwierzytelnionego użytkownika, który nie jest autoryzowany do określonego zasobu. Tak wygląda sytuacja PO.
Z dokumentu IETF na 403:
Serwer, który otrzymuje ważne dane uwierzytelniające, które nie są wystarczające do uzyskania dostępu, powinien odpowiedzieć kodem statusu 403 (zabronione)
źródło
W Mozilli możesz to osiągnąć za pomocą następującego skryptu podczas tworzenia obiektu XMLHttpRequest:
xmlHttp=new XMLHttpRequest(); xmlHttp.mozBackgroundRequest = true; xmlHttp.open("GET",URL,true,USERNAME,PASSWORD); xmlHttp.send(null);
Druga linia zapobiega wyświetlaniu okna dialogowego ....
źródło
Z jakiej technologii serwerowej korzystasz i czy jest jakiś konkretny produkt, którego używasz do uwierzytelniania?
Ponieważ przeglądarka wykonuje tylko swoją pracę, uważam, że musisz zmienić rzeczy po stronie serwera, aby nie zwracać kodu stanu 401. Można to zrobić za pomocą niestandardowych formularzy uwierzytelniania, które po prostu zwracają formularz ponownie, gdy uwierzytelnianie się nie powiedzie.
źródło
W krainie Mozilli ustawienie parametru mozBackgroundRequest XMLHttpRequest ( docs ) na true powoduje zablokowanie tych okien dialogowych i powoduje, że żądania po prostu kończą się niepowodzeniem. Jednak nie wiem, jak dobra jest obsługa różnych przeglądarek (w tym, czy jakość informacji o błędach w tych nieudanych żądaniach jest bardzo dobra w różnych przeglądarkach).
źródło
jan.vdbergh ma prawdę, jeśli możesz zmienić 401 po stronie serwera na inny kod statusu, przeglądarka nie złapie i nie zamaluje wyskakującego okienka. Innym rozwiązaniem może być zmiana nagłówka WWW-Authenticate na inny niestandardowy nagłówek. Nie wierzę, dlaczego inna przeglądarka tego nie obsługuje, w kilku wersjach Firefoksa możemy wykonać żądanie xhr za pomocą mozBackgroundRequest, ale w innych przeglądarkach? tutaj jest ciekawy link do tego wydania w Chromium.
źródło
Mam ten sam problem z MVC 5 i VPN, gdzie za każdym razem, gdy jesteśmy poza strefą DMZ, używając VPN, musimy odpowiedzieć na tę wiadomość przeglądarki. Używając .net, po prostu obsługuję routing błędu za pomocą
<customErrors defaultRedirect="~/Error" > <error statusCode="401" redirect="~/Index"/> </customErrors>
do tej pory zadziałało, ponieważ akcja Indeks pod kontrolerem macierzystym weryfikuje użytkownika. Widok w tej akcji, jeśli logowanie się nie powiedzie, zawiera kontrolki logowania, których używam do logowania użytkownika przy użyciu zapytania LDAP przekazanego do usług katalogowych:
DirectoryEntry entry = new DirectoryEntry("LDAP://OurDomain"); DirectorySearcher Dsearch = new DirectorySearcher(entry); Dsearch.Filter = "(SAMAccountName=" + UserID + ")"; Dsearch.PropertiesToLoad.Add("cn");
Chociaż jak dotąd działało to dobrze i muszę poinformować, że nadal go testuję, a powyższy kod nie miał powodu do uruchomienia, więc podlega usunięciu ... obecnie testowanie obejmuje próbę wykrycia przypadku, w którym drugi zestaw kodu jest już przydatny. Ponownie, jest to w toku, ale ponieważ może to być pomoc lub pobudzić mózg do pewnych pomysłów, postanowiłem to teraz dodać ... Zaktualizuję to o ostateczne wyniki, gdy wszystkie testy zostaną zakończone.
źródło
Używam Node, Express i Passport i zmagałem się z tym samym problemem. Mam to do pracy, jawnie ustawiając
www-authenticate
nagłówek na pusty ciąg. W moim przypadku wyglądało to tak:(err, req, res, next) => { if (err) { res._headers['www-authenticate'] = '' return res.json(err) } }
Mam nadzieję, że to komuś pomoże!
źródło
Dla tych, którzy nie używają języka C #, oto,
ActionAttribute
co zwraca400
zamiast401
i „jaskółki” Podstawowe okno dialogowe uwierzytelniania.public class NoBasicAuthDialogAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { base.HandleUnauthorizedRequest(filterContext); filterContext.Result = new HttpStatusCodeResult(400); } }
użyj w następujący sposób:
[NoBasicAuthDialogAuthorize(Roles = "A-Team")] public ActionResult CarType() { // your code goes here }
Mam nadzieję, że zaoszczędzi ci to trochę czasu.
źródło