2012-03-25 20 views
86

Tôi cần gửi yêu cầu ủy quyền bằng xác thực cơ bản. Tôi đã thực hiện thành công điều này bằng cách sử dụng jquery. Tuy nhiên khi tôi nhận được 401 lỗi cơ bản trình duyệt auth popup được mở ra và jquery ajax lỗi gọi lại không được gọi.Làm cách nào để ngăn trình duyệt gọi popup cơ bản và xử lý lỗi 401 bằng Jquery?

+1

có thể trùng lặp của [Làm thế nào tôi có thể đàn áp thoại xác thực của trình duyệt?] (Http://stackoverflow.com/questions/86105/how-can-i-supress-the-browsers-authentication-dialog) – Korayem

Trả lời

34

Tôi cũng đang gặp vấn đề này gần đây. Vì bạn không thể thay đổi hành vi mặc định của trình duyệt hiển thị popup trong trường hợp của một (authentication cơ bản hoặc tiêu hóa) 401, có hai cách để sửa lỗi này:

  • Thay đổi phản ứng máy chủ để không trả lại 401. Trả lại 200 mã thay vào đó và xử lý điều này trong ứng dụng khách jQuery của bạn.
  • Thay đổi phương thức bạn đang sử dụng để ủy quyền cho giá trị tùy chỉnh trong tiêu đề của bạn. Trình duyệt sẽ hiển thị cửa sổ bật lên cho Cơ bảnThông báo. Bạn phải thay đổi điều này trên cả máy khách và máy chủ.

    tiêu đề: { "Authorization": "BasicCustom" }

Xin hãy nhìn vào this cho một ví dụ của việc sử dụng jQuery với Basic Auth.

+9

WWW-Authenticate: xBasic realm = com.example có thể làm điều đó, cùng với mã trạng thái 401 cổ điển. bài đăng trên blog này cho tôi thấy gợi ý (Tôi không phải là chủ sở hữu của blog) http://loudvchar.blogspot.ca/2010/11/avoiding-browser-popup-for-401.html –

+2

@PM, câu trả lời của blog là một giải pháp hoàn hảo. Lưu ý rằng nếu sử dụng '' bạn không cần phải định nghĩa 'basicAuthenticationFilter' nhưng nên định nghĩa nó là' '. –

+0

Bạn có thể plz cho tôi biết làm thế nào để ghi đè lên các phản ứng trước khi gửi lại cho khách hàng, tôi đang sử dụng jaxrs với auth cơ bản. lớp nào tôi cần ghi đè để sửa đổi phản hồi? –

2

Hoặc, nếu bạn có thể tùy chỉnh phản hồi của máy chủ, bạn có thể trả về 403 Cấm.

Trình duyệt sẽ không mở cửa sổ bật lên xác thực và gọi lại jquery sẽ được gọi.

+4

Điều đó đi ngược lại HTTP 1.1 đặc điểm kỹ thuật, nơi nó được tuyên bố rằng "... Ủy quyền sẽ không giúp đỡ và yêu cầu KHÔNG được lặp lại". –

+0

Nó hợp lệ để nhận 403 trong khi được xác thực cho các tài nguyên bạn không được phép truy cập, 401 phải được gửi đến nơi bạn chưa được xác thực. –

26

Trả về mã trạng thái 400 chung và sau đó xử lý phía máy khách đó.

Hoặc bạn có thể giữ 401 và không trả về tiêu đề WWW-Authenticate, đây thực sự là những gì trình duyệt đang phản hồi với cửa sổ bật lên xác thực. Nếu tiêu đề WWW-Authenticate bị thiếu, thì trình duyệt sẽ không nhắc thông tin đăng nhập.

+5

@MortenHaraldsen Phản hồi 401 là phản hồi thích hợp để đưa ra trong dịp này, vấn đề là trình duyệt sẽ tự động xử lý điều này một cách tự nhiên, thay vì cho phép ứng dụng javascript xử lý nó.Bạn có thể tuân theo tiêu chuẩn, bằng cách không trả lại phản hồi thích hợp mà tiêu chuẩn đề xuất, hoặc bạn có thể chọn không tuân theo tiêu chuẩn, bằng cách trả lại mã phản hồi tiêu chuẩn được khuyến nghị. Chọn lựa của bạn :) – Ibraheem

+0

Trong ứng dụng tốc hành của tôi, tôi đã sửa lỗi này bằng một dòng: 'res.removeHeader ('www-authenticate'); // ngăn trình duyệt thoát khỏi cửa sổ xác thực cơ bản.' – gstroup

+1

@Ibraheem, không thể tự tuyên bố tốt hơn. Tiêu chuẩn được tạo ra bởi những người ngồi xuống và nói chuyện, không nhất thiết là những người ngồi xuống và viết mã. – user2867288

0

Tạo url/đăng nhập, thay vì chấp nhận tham số "người dùng" và "mật khẩu" qua GET và không yêu cầu xác thực cơ bản. Ở đây, sử dụng php, nút, java, bất cứ điều gì và phân tích cú pháp tập tin passwd của bạn và các thông số phù hợp (người dùng/vượt qua) chống lại nó. Nếu có kết quả phù hợp thì hãy chuyển hướng đến http://user:[email protected]/ (điều này sẽ đặt thông tin xác thực trên trình duyệt của bạn) nếu không, gửi phản hồi 401 (không có tiêu đề WWW-Authenticate).

+0

Điều đó sẽ cực kỳ tuyệt vời đối với bất kỳ ai cố gắng đánh cắp tên người dùng/mật khẩu của người đàn ông thuần văn bản trong các cuộc tấn công ở giữa! – Ajax

2

Nếu bạn đang sử dụng Máy chủ IIS, bạn có thể thiết lập Viết lại URL IIS (v2) để viết lại tiêu đề WWW-Authentication vào None trên URL được yêu cầu.

Guide here.

Giá trị bạn muốn thay đổi là response_www_authenticate.

Nếu bạn cần thêm thông tin, hãy thêm nhận xét và tôi sẽ đăng tệp web.config.

+0

Điều này làm việc tuyệt vời. Tôi muốn lưu ý rằng phần "phản ứng" phải được viết là "RESPONSE_www_authenticate" trong URL Rewrite v2 trên IIS 7.5. –

18

Bạn có thể ngăn chặn cơ bản auth popup với yêu cầu url nhìn như thế này:

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

Nếu bạn nhận được 401 lỗi (sai username hoặc password), nó sẽ được xử lý một cách chính xác với callback lỗi jquery. Nó có thể gây ra một số vấn đề bảo mật (trong trường hợp giao thức http thay vì https), nhưng nó hoạt động.

UPD: hỗ trợ giải pháp này sẽ được gỡ bỏ trong Chrome 59

+0

Hoạt động thực sự tốt !!! Cảm ơn – Alist3r

+0

AMAZING !!!! Giải quyết vấn đề của tôi là vấn đề đã thử 192.168.1.1 và router tiếp tục yêu cầu Auth. –

+0

Cảm ơn bạn sir !!!!! Xin lỗi tôi chỉ có thể cung cấp cho bạn 1 upvote. – gab06

2

Sử dụng X-yêu cầu-Với: XMLHttpRequest với tiêu đề yêu cầu của bạn. Vì vậy, tiêu đề phản hồi sẽ không chứa WWW-Authenticate: Basic.

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

Điều đó không có hiệu lực đối với tôi. Bạn đang sử dụng loại máy chủ nào mà WWW-Authenticate không được gửi đi khi bạn đặt XMLHttpRequest? –

+0

@RobertAntonucci nó là apache tomcat – sedhu

9

Như những người khác đã chỉ ra, cách duy nhất để thay đổi hành vi của trình duyệt là để đảm bảo đáp ứng hoặc không chứa một mã số 401 trạng thái hoặc nếu có, không bao gồm các WWW-Authenticate: Basic tiêu đề. Kể từ khi thay đổi mã trạng thái không phải là rất ngữ nghĩa và không mong muốn, một cách tiếp cận tốt là để loại bỏ các tiêu đề WWW-Authenticate. Nếu bạn không thể hoặc không muốn sửa đổi ứng dụng máy chủ web của mình, bạn luôn có thể phân phối hoặc ủy quyền nó thông qua Apache (nếu bạn không sử dụng Apache). Đây là một cấu hình cho Apache để viết lại phản hồi để loại bỏ tiêu đề WWW-Authenticate IFF yêu cầu chứa tiêu đề X-Requested-With: XMLHttpRequest (được đặt theo mặc định bởi các khung Javascript chính như JQuery/AngularJS, v.v.) VÀ phản hồi chứa tiêu đề WWW-Authenticate: Basic.

Được thử nghiệm trên Apache 2.4 (không chắc chắn nếu nó hoạt động với 2.2). Điều này dựa trên mô-đun mod_headers đang được cài đặt. (Trên Debian/Ubuntu, sudo a2enmod headers và khởi động lại 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

Để thực hiện tương tự với Nginx, hãy đặt 'proxy_hide_header WWW-Authenticate; ' – Cuga

2

Nếu tiêu đề WWW-Authenticate được lấy ra, sau đó bạn sẽ không có được bộ nhớ đệm của các thông tin và sẽ không lấy lại tiêu đề ủy quyền trong yêu cầu. Điều đó có nghĩa là bây giờ bạn sẽ phải nhập thông tin đăng nhập cho mọi yêu cầu mới mà bạn tạo ra.

+0

Điều này rất quan trọng, hoàn toàn tại chỗ. –

1

Trong Safari, bạn có thể sử dụng các yêu cầu đồng bộ để tránh trình duyệt hiển thị cửa sổ bật lên. Tất nhiên, yêu cầu đồng bộ chỉ nên được sử dụng trong trường hợp này để kiểm tra thông tin người dùng ... Bạn có thể sử dụng yêu cầu đó trước khi gửi yêu cầu thực sự có thể gây ra trải nghiệm người dùng xấu nếu nội dung (gửi hoặc nhận) khá nặng.

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'); 
Các vấn đề liên quan