N K
N K

Reputation: 3327

Authentication headers are not sending JQuery Ajax

I have web server hosted in Apache Tomcat 7 with Basic authentication. I have Tomcat user 'tomcat' with role 'tomcat' and password 'tomcat'. Following are my web.xml file and script snippet in client side respectively.

Web.xml

<?xml version="1.0" encoding="ASCII"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>testservice</display-name>
  <servlet>
    <description>JAX-RS Tools Generated - Do not modify</description>
    <servlet-name>testservice</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>testservice</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>testservice</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>GET</http-method>
            <http-method>POST</http-method>
        </web-resource-collection>
        <auth-constraint>
            <role-name>tomcat</role-name>
        </auth-constraint>

        <user-data-constraint>
            <!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
    </login-config>
</web-app>

Client script:

<script src="jquery-1.10.2.min.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
    $.ajax({
        type: "GET",
        beforeSend: function (request)
        {
            request.setRequestHeader("Authorization", "Basic  dG9tY2F0OnRvbWNhdA==");
        },
        url: "http://localhost:1222/testservice/rest/test/users",
        dataType:"jsonp",
        success: function(res) {
            alert(res); 
        },
        error: function(err) {
            alert(err);
        }
    });                    
</script>

I'm pretty sure about that there's no problem with Web Service and Basic authentication. But from client script, no authentication headers are sending. I tried header:("Authorization","Basic dG9tY2F0OnRvbWNhdA==") too. But request is sending without authentication headers. Any help will be appreciated.

Upvotes: 3

Views: 26228

Answers (4)

I haven't found a solution for this, only a workaround:

Send the Authorization header using two headers, the standard one and a custom one for IE:

beforeSend: function (jqXHR, settings) {
    if (self._hasAuthInfo()) {
        jqXHR.setRequestHeader("Authorization", self._makeAuthHeader());
        jqXHR.setRequestHeader("IEAuth", self._makeAuthHeader());
    }
}

The server side will check both (the second one only if IE and if the standard one is not present)

Upvotes: 0

mccannf
mccannf

Reputation: 16659

Two things to try:

1) Add the CORS Filter to your Tomcat configuration

add the CORS Filter to your Tomcat configuration. Note Access-Control-Allow-Origins has been purposely left blank below, so no site has access via CORS. But the important parameter that is configured is Access-Control-Allow-Credentials.

<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></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</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>

2) Modify Your Ajax Call

Modify your beforeSend in your ajax call like so:

$.ajax({
    type: "GET",
    beforeSend: function (request)
    {
        request.withCredentials = true;
        request.setRequestHeader("Authorization", "Basic  dG9tY2F0OnRvbWNhdA==");
    },
    url: "http://localhost:1222/testservice/rest/test/users",
    dataType:"jsonp",
    success: function(res) {
        alert(res); 
    },
    error: function(err) {
        alert(err);
    }
});           

Only other thing I noticed is that your web.xml might also need the following:

<security-role>
  <role-name>tomcat</role-name>
</security-role>

Hope this helps.

Upvotes: 4

Ryan Anderson
Ryan Anderson

Reputation: 947

mccannf got us 99% of the way there with a similar issue hover we switched up how we set the withCredentials property and this worked for us. notice we set the xhrFields property. This can been seen within the jQuery documentation for the ajax method here; http://api.jquery.com/jQuery.ajax/

$.ajax({
    type: "GET",
    xhrFields: { withCredentials: true }, 
    beforeSend: function (request)
    {
        request.setRequestHeader("Authorization", "Basic  dG9tY2F0OnRvbWNhdA==");
    },
    url: "http://localhost:1222/testservice/rest/test/users",
    dataType:"jsonp",
    succes: function(res) {
        alert(ers); 
    },
    error: function(err) {
        alert(err);
    }
});

However, we were not using jsonp, simple json.

Upvotes: 0

N K
N K

Reputation: 3327

Found that passing authentication via headers is not working with jQuery ajax with jsonp data type. So tried following and works fine.

$.ajax({
    type: "GET",
    url: "http://tomcat:tomcat@localhost:1222/testservice/rest/test/users",
    dataType:"jsonp",
    success: function(res) {
        alert(res); 
    },
    error: function(err) {
        alert(err);
    }
});  

function callbackMethod(data) {
    alert(data);
}

Upvotes: 2

Related Questions