How to prevent the browser from invoking the base auth popup and handle error 401 using jQuery?

I need to send an authorization request using basic auth. I have successfully implemented this with jquery. However, when I get error 401, the auth browser popup window opens and the jQuery ajax callback is not called.

+96
javascript jquery rest basic-authentication
Mar 25 2018-12-12T00:
source share
11 answers

I also recently ran into this problem. Since you cannot change the default behavior of the browser when a popup appears in case 401 (basic or digest authentication), there are two ways to fix this:

  • Modify the server response so as not to return 401 . Instead, return the 200 code and process it in your jQuery client.
  • Change the method you use for authorization to the custom value in your header. Browsers will display pop-ups for Basic and Digest. You must change this both on the client and on the server.

     headers : { "Authorization" : "BasicCustom" } 

Also note this for an example of using jQuery with basic authentication.

+41
Mar 26 '12 at 13:00
source share

Returns a 400 common status code, and then processes it on the client side.

Or you can save 401 and not return the WWW-Authenticate header to which the browser responds with an authentication pop-up. If the WWW-Authenticate header is missing, the browser will not request credentials.

+31
Jul 04 '13 at 15:11
source share

You can suppress a basic popup with a url request that looks like this:

 https://username:password@example.com/admin/... 

If you get error 401 (wrong username or password), it will be correctly processed using the jquery error callback. This may cause some security issues (in the case of the HTTP protocol instead of https), but it works.

UPD: Support for this solution will be removed in Chrome 59

+17
Oct 06 '14 at 2:43 on
source share

As others have pointed out, the only way to change browser behavior is to make sure that the response either does not contain a 401 status code, or, if there is one, does not include the WWW-Authenticate: Basic header. Since changing the status code is not very semantic and undesirable, removing the WWW-Authenticate header is a good approach. If you cannot or do not want to modify the web server application, you can always serve or proxy the server through Apache (if you are not already using Apache).

Here is the configuration for Apache to overwrite the response to removing the IFF-Authenticate IFF header containing the request contains the X-Requested-With: XMLHttpRequest header X-Requested-With: XMLHttpRequest (which is set by default with the main Javascript frameworks like JQuery / AngularJS, etc.). ) And the response contains the WWW-Authenticate: Basic header.

Tested on Apache 2.4 (not sure if it works with 2.2). It depends on the installed mod_headers module. (On Debian / Ubuntu, sudo a2enmod headers and restart 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> 
+10
Jun 20 '16 at 9:31
source share

If you use an IIS server, you can configure IIS URL rewriting (v2) to rewrite the WWW-Authentication header to None in the requested URL.

The manual is here .

The value you want to change is response_www_authenticate .

If you need more information, add a comment and I will post the web.config file.

+5
Apr 6 '14 at 17:05
source share

Use X-Requested-With: XMLHttpRequest with your request header. Thus, the response header will not contain WWW-Authenticate: Basic.

 beforeSend: function (xhr) { xhr.setRequestHeader('Authorization', ("Basic " .concat(btoa(key)))); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); }, 
+3
Aug 11 '15 at 6:05
source share

Alternatively, if you can customize your server’s response, you can return 403 Forbidden.

The browser will not open the authentication popup and the jquery callback will be called.

+2
Aug 20 '12 at 10:45
source share

If the WWW-Authenticate header is removed, then you will not get credential caching and will not get the authorization header in the request back. This means that now you will need to enter the credentials for each new request that you create.

+2
Oct 08 '16 at 20:12
source share

In Safari, you can use synchronous requests so that the browser does not display a popup. Of course, synchronous requests should only be used in this case to verify the user credentials ... You can use such a request before sending the actual request, which can cause a bad user experience if the content (sent or received) is quite heavy.

  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'); 
+1
Dec 05 '17 at 12:39 on
source share

Make the URL / login, and do not accept the "user" and "password" parameters through GET and do not require basic auth. Here, use php, node, java, whatever, and parse your passwd file and map the parameters (user / pass) to it. If there is a match, redirect to http: // user: pass@domain.com/ (this will set the credentials in your browser), if not, send a 401 response (no WWW authentication header).

0
Jan 07 '14 at 15:56
source share

On the flip side with Spring Boot, I used the usual 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); } } }; } 
0
Jun 06 '19 at 22:30
source share



All Articles