【问题标题】:Cross origin request with CORS filter使用 CORS 过滤器的跨源请求
【发布时间】:2015-04-17 21:10:06
【问题描述】:

我正在尝试从 AngularJS 1.3 应用程序向 REST 服务发出跨源请求。虽然我启用了 CORS 过滤器,但我得到了 403 Forbidden 响应。这是请求(从 chrome 开发工具复制粘贴)。在 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() {

    }

}

【问题讨论】:

    标签: ajax angularjs rest cross-domain cors


    【解决方案1】:

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

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

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

    我同意 Ryan 的观点,您不应该通过 OPTIONS 检查 auth 标头。

    【讨论】:

    • OPTIONS 已被允许:Access-Control-Allow-Methods:POST、GET、HEAD、OPTIONS。在过滤器中我有: response.setHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS");在响应标头中,它显示为允许。
    • @MihaiSerban 是否在 HTTP 服务器上启用(例如在 htaccess/web.config 中)?你用 200 ok 处理它吗?
    • 在 web.xml 中启用了 CORS 过滤器,这就是标题出现在响应中的原因。它被映射到使用的 url 模式。
    • @MihaiSerban 我想你误会了。这与 CORS 标头无关。您的服务器不提供 OPTIONS 请求的问题。您应该将其添加到路由并发送 200 ok 并带有空响应正文和 ofc。相同的 CORS 允许标头。顺便提一句。这个问题与rest和angular无关。
    • 我设法通过删除 x-auth-token 来解决这个问题。这是正确的答案。
    【解决方案2】:

    在预检 CORS 请求的情况下,您需要注意不会在 OPTIONS 请求中发送凭据。如果后者在其响应中发回正确的 CORS 标头,则使用凭证调用目标请求。这就是为什么你有 403 状态码...

    所以你需要调整你的 CORS 过滤器,不要尝试验证这个 OPTIONS 请求。

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

    【讨论】:

    • 是的,我绝对同意你的看法。我会看看我很老的答案来解决这个问题......感谢您指出这一点!
    • 请不要在帖子中添加标语。 SE 确实不鼓励它,它不会在帖子中添加任何内容。
    猜你喜欢
    • 1970-01-01
    • 2016-11-23
    • 1970-01-01
    • 2018-01-07
    • 2012-12-20
    • 2016-05-05
    • 2017-07-22
    • 2011-12-26
    • 2012-01-08
    相关资源
    最近更新 更多