使用CORS过滤器的交叉原始请求

时间:2015-02-17 07:43:35

标签: ajax angularjs rest cross-domain cors

我正在尝试将来自AngularJS 1.3应用程序的跨源请求发送到REST服务。虽然我启用了CORS过滤器,但我收到了403 Forbidden响应。这是请求(从chrome dev工具复制粘贴)。在IE 9上它似乎工作。我在Chrome和Firefox上收到403错误代码。

Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/<path>
Request Method:OPTIONS
Status Code:403 Forbidden
Request Headersview source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en,ro;q=0.8,en-US;q=0.6,en-GB;q=0.4
Access-Control-Request-Headers:x-auth-token, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, ike Gecko) Chrome/40.0.2214.111 Safari/537.36
Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Origin, Accept, x-auth-token, Content-Type,        
Access-Control-Request-Method, Access-Control-Request-Headers
Access-Control-Allow-Methods:POST, GET, HEAD, OPTIONS
Access-Control-Allow-Origin:http://localhost:9000
Content-Length:0
Content-Type:text/plain
Date:Tue, 17 Feb 2015 07:11:24 GMT
Server:Apache-Coyote/1.1

网址没问题。如果我直接将其粘贴到浏览器中就可以了。

交叉原始身份验证有效:

Remote Address:127.0.0.1:8080
Request        
URL:http://localhost:8080/<serviceName>/webapi/authentication/authenticate
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip, deflate
Accept-Language:en,ro;q=0.8,en-US;q=0.6,en-GB;q=0.4
Connection:keep-alive
Content-Length:42
Content-Type:application/json;charset=UTF-8
Host:localhost:8080
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,     like Gecko) Chrome/40.0.2214.111 Safari/537.36
Request Payload
{username: "user", password: "pass"}
Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:9000
Content-Length:100
Content-Type:application/json
Date:Tue, 17 Feb 2015 07:11:24 GMT
Server:Apache-Coyote/1.1
Set-Cookie:JSESSIONID=805B2490C0BA258D7D0FF4235BA49B76; Path=/<appcontext>/;     
HttpOnly

我正在使用Spring Security进行身份验证。交叉原始请求还需要什么?

使用的CORS过滤器:

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

public class CORSFilter2 implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse     servletResponse, FilterChain filterChain) throws IOException, ServletException {
        final HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "http://localhost:9000");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, x-auth-token, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }

}

2 个答案:

答案 0 :(得分:5)

通过CORS非GET请求自动在浏览器中发送预检请求。您应该在HTTP服务器和CORS允许标头中允许OPTIONS方法来提供这些请求。您的服务器应该使用CORS允许标头和200 ok响应预检的空响应。

根据您的评论,问题可能是由x-auth-token请求发送的自定义OPTIONS标头引起的,因此您的服务器以403 forbidden回复。

  

预检调用是一种确定是否允许操作的调用。它   不应该要求凭证来确定我是否可以做某事,它   应该只需要凭据来实际执行。

我同意Ryan,你不应该通过OPTIONS检查auth标题。

答案 1 :(得分:1)

对于预先发出的CORS请求,您需要知道OPTIONS请求中未发送凭据。如果后者在其响应中发回正确的CORS头,则随后使用凭证调用目标请求。这就是为什么你有403状态代码...

因此,您需要调整CORS过滤器,而不是尝试验证此OPTIONS请求。

除了上一个答案,此链接可以帮助您解决问题:https://templth.wordpress.com/2014/11/12/understanding-and-using-cors/

相关问题