I configures my Jetty server to allow cross domain http requests (allowedOrigins = *) and also to allow cross domain authentication (allowCredentials=true) using its CrossOriginFilter. Cross domain http requests without authentication requirement work ok. Now when it comes to http calls that require authentication It doesn't work out using JQuery. I use the following code and followed this example: http://www.aswinanand.com/2009/01/http-basic-authentication-using-ajax/
function login(username, password) {
$.ajax({
type: "GET",
contentType: "application/json",
dataType: "json",
url: url,
beforeSend: function(xhr) {
var base64 = Base64.encode(username + ":" + password);
xhr.setRequestHeader("Authorization", "Basic " + base64);
xhr.withCredentials = true;
},
error: function(data){
alert("error");
},
success: function(data){
alert("success");
}
});
In HTTPFox i see the following request to the server:
OPTIONS /login HTTP/1.1
...
Access-Control-Request-Method GET
Access-Control-Request-Headers authorization,content-type
The server responds with a
HTTP/1.1 204 No Content
...
Allow OPTIONS,GET,HEAD
I also used the options below, which doesnt make a difference.
$.ajax({
...
username: username,
password: password,
...
}
The error function always fires. Anybody an idea what the problem could be?
As the default allowed headers are
X-Requested-With,Content-Type,Accept,Origin
I had to add the headers
authorization,content-type
Found this via the log file
DEBUG [2012-05-27 17:04:02,468] org.eclipse.jetty.servlets.CrossOriginFilter: Headers [authorization,content-type] are not among allowed headers [X-Requested-With, Content-Type, Accept, Origin]
Thanks for all the hints!
The response headers that you set in your application -- when security is not enabled 00 works just fine, as you've attested to. However, when security is enabled, your cross-domain requests fail.
This is likely due to the additional Filter and additional response headers that are set by the security filter in order to generate a response.
To solve this problem, the high level solution is that you must set your response headers prior to the time that the security Filter sets its response headers and/or commits them to the client.
You're also using Jetty; therefore, you can use the Jetty Cross Origin Filter to ensure that the response headers are set in the Filter chain, in the order that they need to be set:
Here is a list of parameters that you can pass into the Filter configuration in web.xml:
allowedOrigins, a comma separated list of origins that are allowed to access the resources. Default value is *, meaning all origins
allowedMethods, a comma separated list of HTTP methods that are allowed to be used when accessing the resources. Default value is GET,POST
allowedHeaders, a comma separated list of HTTP headers that are allowed to be specified when accessing the resources. Default value is X-Requested-With
preflightMaxAge, the number of seconds that preflight requests can be cached by the client. Default value is 1800 seconds, or 30 minutes
allowCredentials, a boolean indicating if the resource allows requests with credentials. Default value is false
By default, the Allowed Origins response header is set to *
, which implies that by default, any request can be made from any domain. You'll need to be sure to modify this to allow only domains that you intend to whitelist, assuming you don't want every request from all domains to be valid:
web.xml entry for the Filter:
<web-app ...>
...
<filter>
<filter-name>cross-origin</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cross-origin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>
Here is a list of additional resources that you may find helpful in solving this particular problem:
Jetty Cross Origin Filter
Access Control Allow Origin not allowed by
Java EE 5 Tutorial - Filtering Requests and Responses
HttpServletResponseWrapper javadoc - You may need this in case you need to override the HttpServletResponse object.
Setting Authentication Header in Servlet via Filter
Differences between ServletResponse and HttpServletResponseWrapper?
How to add response headers based on Content-type; getting Content-type before the response is committed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With