it-swarm-vi.tech

Làm cách nào tôi có thể chặn hộp thoại xác thực của trình duyệt?

Ứng dụng web của tôi có trang đăng nhập gửi thông tin xác thực qua cuộc gọi AJAX. Nếu người dùng nhập đúng tên người dùng và mật khẩu, mọi thứ đều ổn, nhưng nếu không, điều sau đây sẽ xảy ra:

  1. Máy chủ web xác định rằng mặc dù yêu cầu bao gồm tiêu đề Ủy quyền được định dạng tốt, thông tin đăng nhập trong tiêu đề không xác thực thành công.
  2. Máy chủ web trả về mã trạng thái 401 và bao gồm một hoặc nhiều tiêu đề WWW-xác thực liệt kê các loại xác thực được hỗ trợ.
  3. Trình duyệt phát hiện ra rằng phản hồi cuộc gọi của tôi trên đối tượng XMLHttpRequest là một 401 và phản hồi bao gồm các tiêu đề WWW-xác thực. Sau đó, nó bật lên một hộp thoại xác thực hỏi lại tên người dùng và mật khẩu.

Điều này hoàn toàn ổn cho đến bước 3. Tôi không muốn hộp thoại bật lên, tôi muốn xử lý phản hồi 401 trong chức năng gọi lại AJAX của mình. (Ví dụ: bằng cách hiển thị thông báo lỗi trên trang đăng nhập.) Tôi muốn người dùng nhập lại tên người dùng và mật khẩu của họ, nhưng tôi muốn họ thấy biểu mẫu đăng nhập thân thiện, yên tâm của tôi, không phải mặc định của trình duyệt hộp thoại xác thực.

Ngẫu nhiên, tôi không có quyền kiểm soát máy chủ, do đó, việc trả lại mã trạng thái tùy chỉnh (nghĩa là, một cái gì đó không phải là 401) không phải là một tùy chọn.

Có cách nào để tôi có thể chặn hộp thoại xác thực không? Cụ thể, tôi có thể chặn hộp thoại Yêu cầu Xác thực trong Firefox 2 trở lên không? Có cách nào để chặn hộp thoại Connect to [Host] trong IE 6 trở lên không?


Chỉnh sửa
Thông tin bổ sung từ tác giả (ngày 18 tháng 9):
Tôi nên thêm rằng vấn đề thực sự với hộp thoại xác thực của trình duyệt xuất hiện là nó cung cấp không đủ thông tin cho người dùng.

Người dùng vừa nhập tên người dùng và mật khẩu thông qua biểu mẫu trên trang đăng nhập, anh ta tin rằng mình đã nhập cả hai chính xác và anh ta đã nhấp vào nút gửi hoặc nhấn enter. Kỳ vọng của anh ta là anh ta sẽ được đưa đến trang tiếp theo hoặc có thể nói rằng anh ta đã nhập sai thông tin của mình và nên thử lại. Tuy nhiên, thay vào đó anh ta được trình bày với một hộp thoại bất ngờ.

Hộp thoại không xác nhận thực tế anh ta chỉ cần did nhập tên người dùng và mật khẩu. Nó không nói rõ rằng có một vấn đề và anh ta nên thử lại. Thay vào đó, hộp thoại trình bày cho người dùng thông tin khó hiểu như "Trang web nói: '[realm]'." Trong đó [cõi] là một tên cõi ngắn mà chỉ lập trình viên mới có thể yêu thích.

Các nhà thiết kế trình duyệt web lưu ý: không ai sẽ hỏi làm thế nào để chặn hộp thoại xác thực nếu hộp thoại đơn giản là thân thiện hơn với người dùng. Lý do toàn bộ mà tôi đang thực hiện một hình thức đăng nhập là nhóm quản lý sản phẩm của chúng tôi coi các hộp thoại xác thực của trình duyệt là khủng khiếp.

72
dgvid

Tôi không nghĩ điều này là có thể - nếu bạn sử dụng triển khai ứng dụng khách HTTP của trình duyệt, nó sẽ luôn bật lên hộp thoại đó. Hai hack đến với tâm trí:

  1. Có thể Flash xử lý việc này khác nhau (tôi chưa thử), vì vậy việc có một bộ phim flash khiến yêu cầu có thể giúp ích.

  2. Bạn có thể thiết lập 'proxie' cho dịch vụ mà bạn đang truy cập trên máy chủ của riêng mình và để nó sửa đổi các tiêu đề xác thực một chút, để trình duyệt không nhận ra chúng.

17
Marijn

Tôi đã gặp vấn đề tương tự ở đây và kỹ sư phụ trợ tại công ty của tôi đã thực hiện một hành vi được coi là một thông lệ tốt: khi một cuộc gọi đến URL trả về một 401, nếu khách hàng đã đặt tiêu đề X-Requested-With: XMLHttpRequest, máy chủ sẽ bỏ tiêu đề www-authenticate trong phản ứng của nó. 

Tác dụng phụ là cửa sổ bật lên xác thực mặc định không xuất hiện.

Đảm bảo rằng lệnh gọi API của bạn có tiêu đề X-Requested-With được đặt thành XMLHttpRequest. Nếu vậy, không có gì để làm ngoại trừ thay đổi hành vi máy chủ theo thông lệ tốt này ...

44

Trình duyệt bật lên Nhắc đăng nhập khi cả hai điều kiện sau được đáp ứng:

  1. Trạng thái HTTP là 4xx
  2. Tiêu đề WWW-Authenticate có trong phản hồi

Nếu bạn có thể kiểm soát phản hồi HTTP, thì bạn có thể xóa tiêu đề WWW-Authenticate khỏi phản hồi và trình duyệt sẽ không bật hộp thoại đăng nhập.

Nếu bạn không thể kiểm soát phản hồi, bạn có thể thiết lập proxy để lọc tiêu đề WWW-Authenticate khỏi phản hồi.

Theo như tôi biết (cứ tự nhiên sửa lỗi cho tôi nếu tôi sai), không có cách nào để ngăn chặn thông báo đăng nhập một khi trình duyệt nhận được tiêu đề WWW-Authenticate.

14
rustyx

Tôi nhận ra rằng câu hỏi này và câu trả lời của nó rất cũ. Nhưng, tôi đã kết thúc ở đây. Có lẽ những người khác cũng sẽ như vậy.

Nếu bạn có quyền truy cập vào mã cho dịch vụ web trả về 401. Chỉ cần thay đổi dịch vụ để trả về 403 (Bị cấm) trong tình huống này thay vì 401. Trình duyệt sẽ không nhắc nhở thông tin đăng nhập theo 403. 403 mã chính xác cho người dùng được xác thực không được ủy quyền cho một tài nguyên cụ thể. Mà dường như là tình hình của OP.

Từ tài liệu của IETF trên 403:

Một máy chủ nhận được thông tin hợp lệ không phù hợp với đạt được quyền truy cập phải phản hồi với mã trạng thái 403 (Bị cấm)

5
Jim Reineri

Trong Mozilla, bạn có thể đạt được nó với tập lệnh sau khi tạo đối tượng XMLHttpRequest:

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

Dòng thứ 2 ngăn hộp thoại ....

4
Yogesh

Bạn sử dụng công nghệ máy chủ nào và có sản phẩm cụ thể nào bạn sử dụng để xác thực không?

Vì trình duyệt chỉ thực hiện công việc của nó, tôi tin rằng bạn phải thay đổi mọi thứ ở phía máy chủ để không trả lại mã trạng thái 401. Điều này có thể được thực hiện bằng cách sử dụng các biểu mẫu xác thực tùy chỉnh chỉ đơn giản là trả lại biểu mẫu khi xác thực thất bại.

3
jan.vdbergh

jan.vdbergh có một sự thật, nếu bạn có thể thay đổi 401 ở phía máy chủ cho một mã trạng thái khác, trình duyệt sẽ không bắt và Vẽ cửa sổ bật lên . tiêu đề. Tôi không tin tại sao trình duyệt khác nhau không thể hỗ trợ nó, trong một vài phiên bản Firefox, chúng tôi có thể thực hiện yêu cầu xhr với mozBackgroundRequest, nhưng trong các trình duyệt khác ?? ở đây, có một liên kết thú vị với vấn đề này trong Chromium.

2
Kalamarico

Trong vùng đất Mozilla, việc đặt tham số mozBackgroundRequest của XMLHttpRequest ( docs ) thành đúng sẽ loại bỏ các hộp thoại đó và khiến các yêu cầu đơn giản thất bại. Tuy nhiên, tôi không biết hỗ trợ trình duyệt chéo tốt như thế nào (bao gồm cả chất lượng thông tin lỗi đối với các yêu cầu không thành công đó có tốt không trên các trình duyệt.)

2
rakslice

Tôi gặp vấn đề tương tự với MVC 5 và VPN khi bất cứ khi nào chúng tôi ở ngoài DMZ bằng VPN, chúng tôi thấy mình phải trả lời tin nhắn trình duyệt này. Sử dụng .net Tôi chỉ cần xử lý việc định tuyến lỗi bằng cách sử dụng

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

cho đến nay nó đã hoạt động được vì hành động Index trong bộ điều khiển gia đình xác nhận người dùng. Chế độ xem trong hành động này, nếu đăng nhập không thành công, có các điều khiển đăng nhập mà tôi sử dụng để đăng nhập người dùng bằng cách sử dụng truy vấn LDAP được chuyển vào Dịch vụ thư mục:

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

Mặc dù điều này đã hoạt động tốt cho đến nay và tôi phải cho bạn biết rằng tôi vẫn đang thử nghiệm nó và đoạn mã trên không có lý do gì để chạy nên nó có thể bị xóa ... thử nghiệm hiện bao gồm cố gắng khám phá trường hợp trong đó tập thứ hai mã là của bất kỳ sử dụng nhiều hơn. Một lần nữa, đây là một công việc đang tiến triển, nhưng vì nó có thể là một số trợ giúp hoặc chạy bộ não của bạn cho một số ý tưởng, tôi quyết định thêm nó ngay bây giờ ... Tôi sẽ cập nhật nó với kết quả cuối cùng sau khi tất cả các thử nghiệm được thực hiện.

1
Clarence

Tôi đang sử dụng Node, Express & Passport và đang phải vật lộn với cùng một vấn đề. Tôi đã làm cho nó hoạt động bằng cách đặt rõ ràng tiêu đề www-authenticate thành một chuỗi trống. Trong trường hợp của tôi, nó trông như thế này:

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

Tôi hy vọng điều đó sẽ giúp được ai đó!

0
John Knotts

Đối với những người sử dụng C # ở đây ActionAttribute trả về 400 thay vì 401 và 'nuốt' hộp thoại xác thực cơ bản.

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

sử dụng như sau:

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

Hy vọng điều này sẽ giúp bạn tiết kiệm thời gian.

0
Matas Vaitkevicius