developer tip

브라우저의 인증 대화 상자를 숨기려면 어떻게해야합니까?

copycodes 2020. 10. 17. 10:40
반응형

브라우저의 인증 대화 상자를 숨기려면 어떻게해야합니까?


내 웹 애플리케이션에는 AJAX 호출을 통해 인증 자격 증명을 제출하는 로그인 페이지가 있습니다. 사용자가 올바른 사용자 이름과 비밀번호를 입력하면 모든 것이 정상이지만 그렇지 않은 경우 다음이 발생합니다.

  1. 웹 서버는 요청에 올바른 형식의 Authorization 헤더가 포함되어 있지만 헤더의 자격 증명이 성공적으로 인증되지 않았 음을 확인합니다.
  2. 웹 서버는 401 상태 코드를 반환하고 지원되는 인증 유형을 나열하는 하나 이상의 WWW-Authenticate 헤더를 포함합니다.
  3. 브라우저는 XMLHttpRequest 개체에 대한 내 호출에 대한 응답이 401이고 응답에 WWW-Authenticate 헤더가 포함되어 있음을 감지합니다. 그런 다음 사용자 이름과 암호를 다시 묻는 인증 대화 상자가 나타납니다.

3 단계까지는 괜찮습니다. 대화 상자가 팝업되는 것을 원하지 않고 AJAX 콜백 함수에서 401 응답을 처리하고 싶습니다. (예를 들어, 로그인 페이지에 오류 메시지를 표시합니다.) 물론 사용자가 사용자 이름과 비밀번호를 다시 입력하기를 원하지만 브라우저의 추악한 기본값이 아닌 친근하고 안심할 수있는 로그인 양식을 보길 바랍니다. 인증 대화 상자.

덧붙여서 저는 서버를 제어 할 수 없으므로 사용자 지정 상태 코드 (예 : 401 이외의 코드)를 반환하도록하는 것은 옵션이 아닙니다.

인증 대화 상자를 숨길 수있는 방법이 있습니까? 특히 Firefox 2 이상에서 인증 필요 대화 상자를 표시하지 않을 수 있습니까? IE 6 이상에서 [호스트]에 연결 대화 상자 를 표시하지 않는 방법이 있습니까?



저자의 추가 정보 편집 (9 월 18 일) :
브라우저 인증 대화창이 뜨는 진짜 문제는 사용자에게 정보가 부족하다는 점이라고 덧붙여 야합니다.

사용자는 로그인 페이지의 양식을 통해 사용자 이름과 비밀번호를 입력했으며, 둘 다 올바르게 입력했다고 믿고 제출 버튼을 클릭하거나 Enter 키를 누릅니다. 그의 기대는 그가 다음 페이지로 이동하거나 자신의 정보를 잘못 입력 했으므로 다시 시도해야한다는 것입니다. 그러나 대신 예기치 않은 대화 상자가 나타납니다.

대화는 그가 단지 사실을 전혀 인정하지 않으며 사용자 이름과 암호를 입력합니다. 문제가 있었으며 다시 시도해야한다는 내용이 명확하지 않습니다. 대신 대화 상자는 "사이트에 ' [realm] '이라고 표시됩니다." 와 같은 비밀 정보를 사용자에게 표시합니다 . 여기서 [realm] 은 프로그래머 만이 좋아할 수있는 짧은 영역 이름입니다.

웹 브라우저 설계자들은주의를 기울입니다. 대화 자체가 단순히 사용자 친화적 인 경우 인증 대화 상자를 억제하는 방법을 묻는 사람은 없습니다. 전체 I는 로그인 양식을하고있는 중이 야한다는 이유는 우리의 제품 관리 팀은 바르게 브라우저 '인증 대화 상자가 끔찍한 것으로 간주한다는 것입니다.


이것이 가능하지 않다고 생각합니다. 브라우저의 HTTP 클라이언트 구현을 사용하면 항상 해당 대화 상자가 나타납니다. 두 가지 핵이 떠 오릅니다.

  1. Flash가 이것을 다르게 처리 할 수 ​​있으므로 (아직 시도하지 않았 음) Flash 동영상을 요청하면 도움이 될 수 있습니다.

  2. 자신의 서버에서 액세스하는 서비스에 대해 '프록시'를 설정하고 브라우저가 인식하지 못하도록 인증 헤더를 약간 수정하도록 할 수 있습니다.


여기에서 동일한 문제가 발생했고 회사의 백엔드 엔지니어는 분명히 좋은 방법으로 간주되는 동작을 구현했습니다. URL 호출이 401을 반환 할 때 클라이언트가 헤더를 설정 한 X-Requested-With: XMLHttpRequest경우 서버 www-authenticate는 해당 헤더를 삭제합니다. 응답.

부작용은 기본 인증 팝업이 나타나지 않는다는 것입니다.

API 호출에 X-Requested-With헤더가로 설정되어 있는지 확인하십시오 XMLHttpRequest. 그렇다면이 모범 사례에 따라 서버 동작을 변경하는 것 외에는 할 일이 없습니다.


브라우저는 다음 조건이 모두 충족되면 로그인 프롬프트를 표시합니다.

  1. HTTP 상태는 4xx입니다.
  2. WWW-Authenticate 응답에 헤더가 있습니다.

HTTP 응답을 제어 할 수있는 경우 응답에서 WWW-Authenticate헤더를 제거 할 수 있으며 브라우저는 로그인 대화 상자를 표시하지 않습니다.

응답을 제어 할 수없는 경우 응답에서 WWW-Authenticate헤더 를 필터링하도록 프록시를 설정할 수 있습니다 .

내가 아는 한 (내가 틀렸다면 자유롭게 수정하십시오) 브라우저가 WWW-Authenticate헤더를 받으면 로그인 프롬프트를 막을 방법이 없습니다 .


나는이 질문과 그 대답이 매우 오래되었다는 것을 알고 있습니다. 하지만 여기까지 왔어요. 아마도 다른 사람들도 마찬가지 일 것입니다.

401을 반환하는 웹 서비스에 대한 코드에 액세스 할 수있는 경우이 상황에서 401 대신 403 (금지)을 반환하도록 서비스를 변경하면됩니다. 브라우저는 403에 대한 응답으로 자격 증명을 요구하지 않습니다. 403은 특정 리소스에 대한 권한이없는 인증 된 사용자에 대한 올바른 코드. OP의 상황 인 것 같습니다.

403의 IETF 문서에서 :

액세스 권한을 얻기에 적절하지 않은 유효한 자격 증명을받은 서버는 403 (금지됨) 상태 코드로 응답해야합니다.


Mozilla에서는 XMLHttpRequest 객체를 만들 때 다음 스크립트를 사용하여 수행 할 수 있습니다.

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

두 번째 줄은 대화 상자를 막습니다 ....


What server technology do you use and is there a particular product you use for authentication?

Since the browser is only doing its job, I believe you have to change things on the server side to not return a 401 status code. This could be done using custom authentication forms that simply return the form again when the authentication fails.


In Mozilla land, setting the mozBackgroundRequest parameter of XMLHttpRequest (docs) to true suppresses those dialogs and causes the requests to simply fail. However, I don't know how good cross-browser support is (including whether the the quality of the error info on those failed requests is very good across browsers.)


jan.vdbergh has the truth, if you can change the 401 on server side for another status code, the browser won't catch and paint the pop-up. Another solution could be change the WWW-Authenticate header for another custom header. I dont't believe why the different browser can't support it, in a few versions of Firefox we can do the xhr request with mozBackgroundRequest, but in the other browsers?? here, there is an interesting link with this issue in Chromium.


I have this same issue with MVC 5 and VPN where whenever we are outside the DMZ using the VPN, we find ourselves having to answer this browser message. Using .net I simply handle the routing of the error using

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

thus far it has worked because the Index action under the home controller validates the user. The view in this action, if logon is unsuccessful, has login controls that I use to log the user in using using LDAP query passed into Directory Services:

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

While this has worked fine thus far, and I must let you know that I am still testing it and the above code has had no reason to run so it's subject to removal... testing currently includes trying to discover a case where the second set of code is of any more use. Again, this is a work in progress, but since it could be of some assistance or jog your brain for some ideas, I decided to add it now... I will update it with the final results once all testing is done.


For those unsing C# here's ActionAttribute that returns 400 instead of 401, and 'swallows' Basic auth dialog.

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

use like following:

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

Hope this saves you some time.


I'm using Node, Express & Passport and was struggling with the same issue. I got it to work by explicitly setting the www-authenticate header to an empty string. In my case, it looked like this:

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

I hope that helps someone!

참고URL : https://stackoverflow.com/questions/86105/how-can-i-suppress-the-browsers-authentication-dialog

반응형