기본 인증을 사용하여 인증 요청을 보내야합니다. jquery를 사용하여 성공적으로 구현했습니다. 그러나 401 오류가 발생하면 기본 인증 브라우저 팝업이 열리고 jquery ajax 오류 콜백이 호출되지 않습니다.
기본 인증을 사용하여 인증 요청을 보내야합니다. jquery를 사용하여 성공적으로 구현했습니다. 그러나 401 오류가 발생하면 기본 인증 브라우저 팝업이 열리고 jquery ajax 오류 콜백이 호출되지 않습니다.
답변:
나도 최근에이 문제에 직면했다. 401
( 기본 또는 다이제스트 인증)의 경우 팝업을 표시하는 브라우저의 기본 동작을 변경할 수 없기 때문에이 문제를 해결하는 두 가지 방법이 있습니다.
401
. 반환200
대신 코드를 jQuery 클라이언트에서 처리하십시오.인증에 사용하는 방법을 헤더의 사용자 지정 값으로 변경합니다. 브라우저는 기본 및 다이제스트에 대한 팝업을 표시합니다 . 클라이언트와 서버 모두에서이를 변경해야합니다.
headers : {
"Authorization" : "BasicCustom"
}
도 살펴 보시기 바랍니다 이 기본 인증과 jQuery를 사용하는 예를 들어.
<security:http-basic/>
정의 할 필요는 basicAuthenticationFilter
없지만 <security:http-basic entry-point-ref="myBasicAuthenticationEntryPoint"/>
.
401
및 WWW-Authenticate:Bearer WWW-Authenticate:NTLM WWW-Authenticate:Negotiate
음주 당신이 될 것이라고 이유를 알고
일반 400 상태 코드를 반환 한 다음 해당 클라이언트 측을 처리합니다.
또는 401을 유지하고 WWW-Authenticate 헤더를 반환하지 않을 수 있습니다. 실제로 브라우저가 인증 팝업으로 응답하는 것입니다. WWW-Authenticate 헤더가없는 경우 브라우저는 자격 증명을 요구하지 않습니다.
res.removeHeader('www-authenticate'); // prevents browser from popping up a basic auth window.
다음과 같은 요청 URL로 기본 인증 팝업을 억제 할 수 있습니다.
https://username:password@example.com/admin/...
401 오류 (잘못된 사용자 이름 또는 암호)가 발생하면 jquery 오류 콜백으로 올바르게 처리됩니다. 일부 보안 문제를 일으킬 수 있지만 (https 대신 http 프로토콜의 경우) 작동합니다.
UPD : 이 솔루션 지원은 Chrome 59에서 제거됩니다.
https://user:pass@host/
2017 년 6 월경 M59에서 포함 된 자격 증명에 대한 지원을 중단 할 예정입니다 . 자세한 내용은 이 chromestatus 블로그 게시물 을 참조하세요.
다른 사람들이 지적했듯이 브라우저의 동작을 변경하는 유일한 방법은 응답에 401 상태 코드가 포함되지 않았는지 또는 포함 된 경우 WWW-Authenticate: Basic
헤더를 포함하지 않는지 확인하는 것 입니다. 상태 코드를 변경하는 것은 그다지 의미가없고 바람직하지 않으므로 WWW-Authenticate
헤더 를 제거하는 것이 좋습니다 . 웹 서버 애플리케이션을 수정할 수 없거나 수정할 수없는 경우 언제든지 Apache를 통해 제공하거나 프록시 할 수 있습니다 (아파치를 아직 사용하지 않는 경우).
다음은 요청에 포함 된 WWW-Authenticate 헤더 IFF를 제거하기 위해 응답을 다시 작성하는 Apache의 구성입니다 X-Requested-With: XMLHttpRequest
(JQuery / AngularJS 등의 주요 Javascript 프레임 워크에서 기본적으로 설정 됨). 헤더 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>
proxy_hide_header WWW-Authenticate;
X-Requested-With : XMLHttpRequest를 요청 헤더와 함께 사용하십시오. 따라서 응답 헤더에는 WWW-Authenticate : Basic이 포함되지 않습니다.
beforeSend: function (xhr) {
xhr.setRequestHeader('Authorization', ("Basic "
.concat(btoa(key))));
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
},
IIS 서버를 사용하는 경우 IIS URL 다시 쓰기 (v2) WWW-Authentication
를 None
설정하여 요청 된 URL에 헤더를 다시 쓸 수 있습니다.
변경하려는 값은 response_www_authenticate
입니다.
더 많은 정보가 필요한 경우 의견을 추가하면 web.config 파일을 게시하겠습니다.
WWW-Authenticate 헤더가 제거되면 자격 증명 캐싱을 얻지 못하고 요청에서 Authorization 헤더를 반환하지 않습니다. 즉, 이제 생성하는 모든 새 요청에 대해 자격 증명을 입력해야합니다.
또는 서버 응답을 사용자 정의 할 수있는 경우 403 Forbidden을 반환 할 수 있습니다.
브라우저는 인증 팝업을 열지 않고 jquery 콜백이 호출됩니다.
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');
GET을 통해 "user"및 "password"매개 변수를 허용하고 기본 인증이 필요하지 않은 것보다 / login URL을 만드십시오. 여기에서 php, node, java 등을 사용하고 passwd 파일을 구문 분석하고 매개 변수 (user / pass)를 일치시킵니다. 일치하는 항목이 있으면 http : // user : pass@domain.com/ (브라우저에 자격 증명이 설정 됨) 로 리디렉션하고 그렇지 않은 경우 401 응답을 보냅니다 (WWW-Authenticate 헤더 없음).
Spring Boot의 뒷면에서 사용자 지정 BasicAuthenticationEntryPoint를 사용했습니다.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().authorizeRequests()
...
.antMatchers(PUBLIC_AUTH).permitAll()
.and().httpBasic()
// https://www.baeldung.com/spring-security-basic-authentication
.authenticationEntryPoint(authBasicAuthenticationEntryPoint())
...
@Bean
public BasicAuthenticationEntryPoint authBasicAuthenticationEntryPoint() {
return new BasicAuthenticationEntryPoint() {
{
setRealmName("pirsApp");
}
@Override
public void commence
(HttpServletRequest request, HttpServletResponse response, AuthenticationException authEx)
throws IOException, ServletException {
if (request.getRequestURI().equals(PUBLIC_AUTH)) {
response.sendError(HttpStatus.PRECONDITION_FAILED.value(), "Wrong credentials");
} else {
super.commence(request, response, authEx);
}
}
};
}