3

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.

2
  • Your "success" key is misspelled as "succes" by the way in the ajax call. Commented Dec 8, 2015 at 21:13
  • @kuanb, You're correct, but that won't help anyway for this situation. Commented Dec 9, 2015 at 6:06

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

From client side request header does not contain the Authorization entry (Inspected the network traffic). While testing in browser it's asking for the credentials.
Yes, a JS request will behave differently from a browser request. Are you saying you made the changes above and still no authorization headers are being passed?
Passing authentication via headers is not working with jQuery ajax with jsonp data type
Setting request.withCredentials = true; in the beforeSend method did not work for me. We ended up setting it within the ajax properties more explicitly like so $.ajax({ type: "GET", xhrFields: { withCredentials: true } And this worked. Hope this helps someone!
2

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);
}

2 Comments

Can you explain what you changed?
@kuanb, Passed credential via url. (tomcat as username and password)
0

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.

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.