使用 CORS 过滤器的跨源请求
Posted
技术标签:
【中文标题】使用 CORS 过滤器的跨源请求【英文标题】:Cross origin request with CORS filter 【发布时间】: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()
【问题讨论】:
【参考方案1】:通过 CORS 非GET
请求在浏览器中自动发送预检请求。您应该在 HTTP 服务器上允许 OPTIONS
方法,并且在 CORS 中允许标头为这些请求提供服务。您的服务器应使用 CORS 允许标头和 200 ok
响应预检的空响应正文。
根据您的 cmets,问题可能是由您的自定义 x-auth-token
标头引起的,该标头不是由 OPTIONS
请求发送的,因此您的服务器以 403 forbidden
响应。
CORS preflight issues in Firefox and Chrome预检调用是用于确定是否允许操作的调用。它 不应该需要凭据来确定我是否可以做某事,它 应该只需要凭据来实际执行它。
我同意 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 确实不鼓励它,它不会在帖子中添加任何内容。以上是关于使用 CORS 过滤器的跨源请求的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Angular 2 在 POST 上启用 ASP.NET MVC 4 中的跨源请求