8

我将我的 Jetty 服务器配置为允许跨域 http 请求 (allowedOrigins = *) 并允许使用其 CrossOriginFilter 进行跨域身份验证 (allowCredentials=true)。没有身份验证要求的跨域 http 请求可以正常工作。现在,当涉及到需要身份验证的 http 调用时,使用 JQuery 无法解决。我使用以下代码并遵循此示例: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"); 
    }
});

在 HTTPFox 中,我看到对服务器的以下请求:

OPTIONS /login HTTP/1.1
...
Access-Control-Request-Method   GET
Access-Control-Request-Headers  authorization,content-type

服务器响应一个

HTTP/1.1 204 No Content
...
Allow   OPTIONS,GET,HEAD

我还使用了下面的选项,这并没有什么不同。

$.ajax({
    ...
    username: username,
    password: password,
    ...
}

错误函数总是触发。有人知道问题可能是什么吗?

4

3 回答 3

5

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!

于 2012-05-27T17:16:09.053 回答
3

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:

于 2012-05-26T22:35:19.480 回答
0

For SOAP stuff, the allowed headers should also include messagetype,soapaction

Beware that no wildcard is allowed to configure the allowed headers...

于 2012-07-11T16:22:49.657 回答