Eturcim
Eturcim

Reputation: 818

Why Chrome and Firefox have not the same behaviour with CORS ajax call with basic auth?

For the context, I am attempting to cross-site call an API wich need the user to be authenticated with basic auth. The Tomcat (7.0.43) serving the API is set to allow cross-origin calls with authentication.

I am using jquery.ajax, passing the following options :

xhrOtpions = {
        url: "http://localhost:8080/api/v1/ressource",
        dataType: 'json',
        username: "user",
        password: "pass",
        xhrFields: {
          withCredentials: true
        }
      }

With Chrome (45), the request succeed, with Firefox (41), no request is sent and the error message is Access to restricted URI denied

To make the call work on Firefox, I change the options to applied what I read from the related jquery issue on github :

xhrActiveBuilds = {
        url: "http://localhost:8080/api/v1/ressource",
        dataType: 'json',
        username: "user",
        password: "pass",
        xhrFields: {
          withCredentials: true
        },            
        beforeSend: function (xhr) {
          xhr.setRequestHeader ("Authorization",  "Basic <encoded_credentials>")
        }
      }

This does not change anything for FF, still the same error. On Chrome, there is now a preflight OPTIONS request sent, which is failing with a 403 forbidden response code.

Below the CORS filter configuration of the Tomcat server:

 <filter>
    <filter-name>CorsFilter</filter-name>
      <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
      <param-name>cors.allowed.origins</param-name>
      <param-value>http://localhost:1081</param-value>
    </init-param>
    <init-param>
      <param-name>cors.allowed.methods</param-name>
      <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
      <param-name>cors.allowed.headers</param-name>
      <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
    </init-param>
    <init-param>
      <param-name>cors.exposed.headers</param-name>
      <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials,Access-Control-Allow-Authorization</param-value>
    </init-param>
    <init-param>
      <param-name>cors.support.credentials</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>cors.preflight.maxage</param-name>
      <param-value>10</param-value>
    </init-param>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Upvotes: 1

Views: 969

Answers (1)

Eturcim
Eturcim

Reputation: 818

I finally figured out the 2 problems.

  • Server side: I added authorization to the cors.allowed.headers
  • Client side: I replaced the option with:

    xhrActiveBuilds = {
      url: "http://localhost:8080/api/v1/ressource",
      dataType: 'json',
      xhrFields: { withCredentials: true },
      beforeSend: function (xhr) {
        xhr.setRequestHeader ("Authorization",  "Basic <encoded_credentials>")
      }
    }
    

Notice that I've removed the username and password as their are causing the request to fail on FF because of jQuery implementation (see)

Upvotes: 1

Related Questions