2012-03-25 22 views
86

我需要使用基本身份驗證發送授權請求。我已經成功實現了這個使用jQuery。但是,當我得到401錯誤基本身份驗證瀏覽器彈出窗口打開和jQuery Ajax錯誤回調沒有被調用。如何防止瀏覽器使用Jquery調用基本的auth彈出窗口並處理401錯誤?

+1

的可能重複[我怎樣可以禁止瀏覽器的身份驗證對話框?(http://stackoverflow.com/questions/86105/how-can-i-supress-the-browsers-authentication-dialog) – Korayem 2015-12-07 05:53:26

回答

34

我最近也在面對這個問題。既然你不能改變瀏覽器的默認顯示401(基本消化認證)的情況下,在彈出的行爲,有兩種方法來解決這個問題:

  • 更改服務器響應不返回一個401.返回一個200代碼,並在你的jQuery客戶端處理這個。
  • 將您用於授權的方法更改爲標題中的自定義值。瀏覽器將顯示彈出窗口基本摘要。您必須在客戶端和服務器上更改此設置。

    頭:{ 「授權」: 「BasicCustom」 }

也請看一看this對於使用jQuery使用基本身份驗證的一個例子。

+9

WWW-Authenticate:xBasic realm = com.example可以與經典的401狀態碼一起使用。此博客文章向我展示了提示(我不是博客的所有者)http://loudvchar.blogspot.ca/2010/11/avoiding-browser-popup-for-401.html – 2012-12-13 02:26:33

+2

@PM,博客的答案是完美的解決方案。請注意,如果使用'',則不需要定義'basicAuthenticationFilter',但應將其定義爲''。 – 2013-07-17 06:32:46

+0

你可以告訴我如何在發送回客戶端之前重寫響應,我使用帶有基本身份驗證的jaxrs。哪些類需要重寫以修改響應? – 2017-04-18 12:46:37

2

或者,如果您可以自定義您的服務器響應,則可以返回403 Forbidden。

瀏覽器將不會打開身份驗證彈出窗口並調用jquery回調函數。

+4

這違背了HTTP 1.1規範,其中規定「......授權無效,請求不應重複」。 – 2013-02-27 11:04:38

+0

對於您不允許訪問的資源進行身份驗證時接收403是有效的,401應在您尚未通過身份驗證的位置發送。 – 2013-07-17 06:21:41

26

返回一個通用的400狀態碼,然後處理該客戶端。

或者您可以保留401,並且不返回WWW-Authenticate標頭,這實際上是瀏覽器使用身份驗證彈出窗口響應的內容。如果缺少WWW-Authenticate標頭,則瀏覽器不會提示輸入憑據。

+5

@MortenHaraldsen 401響應是在這種情況下給出的正確響應,問題是瀏覽器自動處理這個本地,而不是讓JavaScript應用程序來處理它。通過返回標準建議的響應代碼,您可以堅持標準,不返回標準建議的正確響應,或者您可以選擇不遵守標準。把你的選擇:) – Ibraheem 2015-02-26 19:30:37

+0

在我的快車應用程序中,我用一行來解決這個問題:'res.removeHeader('www-authenticate'); //防止瀏覽器彈出一個基本的認證窗口。「# – gstroup 2016-02-13 00:05:00

+1

@Ibraheem,我自己不能說得更好。標準由坐下來談話的人創建,而不一定是坐下來進行編碼的人。 – user2867288 2016-08-01 17:33:54

0

通過GET接受「user」和「password」參數並且不需要基本身份驗證,可以設置/ login url。在這裏,使用php,node,java,然後解析你的passwd文件並匹配參數(user/pass)。如果匹配,則重定向到http://user:[email protected]/(這將在您的瀏覽器上設置憑證),如果沒有,發送401響應(沒有WWW-Authenticate頭)。

+0

對於任何試圖在中間攻擊中嗅探純文本用戶名/密碼的人來說,這將是超級棒! – Ajax 2018-01-09 19:58:52

2

如果您使用的是IIS服務器,則可以設置IIS URL重寫(v2),以在請求的URL上將WWW-Authentication標頭重寫爲None

Guide here

要更改的值是response_www_authenticate

如果您需要更多信息,請添加評論,我將發佈web.config文件。

+0

這很好。我想說明的是,在IIS 7.5的URL Rewrite v2中,「響應」部分必須寫爲「RESPONSE_www_authenticate」。 – 2016-06-21 13:42:44

18

可以抑制基本身份驗證彈出與請求的URL看起來像這樣:

https://username:[email protected]/admin/... 

如果你得到401錯誤(錯誤的用戶名和密碼),它會使用jQuery錯誤回調進行正確的處理。它可能會導致一些安全問題(如果是http協議而不是https),但它是有效的。

UPD:該解決方案將支持在Chrome 59

+0

工程真的很好!謝謝 – Alist3r 2015-01-12 10:24:47

+0

令人驚歎!解決了我的問題,因爲問題是嘗試192.168.1.1和路由器不斷要求Auth。 – 2015-02-05 10:00:58

+0

謝謝先生!!!!!對不起,我只能給你1 upvote。 – gab06 2015-07-07 13:44:30

2

使用X-要求,隨着中刪除:XMLHttpRequest的與你的請求頭。 所以響應頭將不包含WWW-Authenticate:Basic。

beforeSend: function (xhr) { 
        xhr.setRequestHeader('Authorization', ("Basic " 
         .concat(btoa(key)))); 
        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
       }, 
+0

這對我沒有任何影響。你使用的是什麼類型的服務器,當你設置XMLHttpRequest時,不包括WWW-Authenticate? – 2015-10-21 15:14:36

+0

@RobertAntonucci它是apache tomcat – sedhu 2016-03-26 20:38:36

9

正如其他人所指出的那樣,改變瀏覽器的行爲的唯一方法是,以確保響應要麼不包含401個狀態碼或如果這樣做,不包括WWW-Authenticate: Basic頭。由於更改狀態代碼不是很有意義且不受歡迎,所以一個好方法是刪除頭文件WWW-Authenticate。如果你不能或不想修改你的Web服務器應用程序,你總是可以通過Apache服務或代理它(如果你沒有使用Apache)。

這裏是Apache重寫響應來刪除WWW-Authenticate頭的配置請求包含的IFF包含頭文件X-Requested-With: XMLHttpRequest(默認情況下由主要的Javascript框架如JQuery/AngularJS等設置)並且響應包含標題WWW-Authenticate: Basic

在Apache 2.4上測試(不確定它是否適用於2.2)。 這依賴於正在安裝的mod_headers模塊。 (在Debian/Ubuntu的,sudo a2enmod headers和重啓Apache)

<Location /> 
      # Make sure that if it is an XHR request, 
      # we don't send back basic authentication header. 
      # This is to prevent the browser from displaying a basic auth login dialog. 
      Header unset WWW-Authenticate "expr=req('X-Requested-With') == 'XMLHttpRequest' && resp('WWW-Authenticate') =~ /^Basic/" 
    </Location> 
+1

要做到與Nginx一樣,請設置'proxy_hide_header WWW-Authenticate;' – Cuga 2017-03-28 15:27:05

2

如果WWW身份驗證頭被刪除,那麼你就不會得到證書的緩存和不會回來Authorization頭的請求。這意味着現在您必須輸入您生成的每個新請求的憑據。

+0

這是非常重要的,絕對有用。 – 2017-02-20 11:08:12

1

在Safari中,您可以使用同步請求來避免瀏覽器顯示彈出窗口。當然,在這種情況下,只應使用同步請求來檢查用戶憑證......如果發送或接收的內容非常繁重,則可以在發送實際請求之前使用此類請求,這可能會導致不良的用戶體驗。

var xmlhttp=new XMLHttpRequest; 
    xmlhttp.withCredentials=true; 
    xmlhttp.open("POST",<YOUR UR>,false,username,password); 
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
    xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
相關問題