使用 CORS 过滤器的跨源请求
Cross origin request with CORS filter
我正在尝试从 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
URL 没问题。如果我直接将它粘贴到浏览器中,它就可以工作了。
跨源身份验证有效:
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 安全性进行身份验证。跨源请求还需要什么?
使用的 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() {
}
}
通过 CORS 非 GET
请求自动在浏览器中发送预检请求。您应该在 HTTP 服务器上允许 OPTIONS
方法,并在 CORS 中允许 headers 来处理这些请求。您的服务器应该响应 CORS allow headers 和 200 ok
对 preflights 的空响应 body。
根据您的评论,问题可能是由您的自定义 x-auth-token
header 引起的,它不是由 OPTIONS
请求发送的,因此您的服务器响应 403 forbidden
.
A preflight call is a call to determine if an action is allowed. It
should not require credentials to determine if I can do something, it
should only require credentials to actually do it.
我同意 Ryan 的观点,你不应该通过选项检查身份验证 headers。
对于预检 CORS 请求,您需要注意 OPTIONS
请求中不会发送凭据。如果后者在其响应中发回正确的 CORS headers,则使用凭据调用目标请求。这就是为什么你有 403 状态码...
所以你需要调整你的 CORS 过滤器,不要尝试验证这个 OPTIONS
请求。
除了前面的答案,这个 link 可以帮助您解决问题:https://templth.wordpress.com/2014/11/12/understanding-and-using-cors/。
我正在尝试从 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
URL 没问题。如果我直接将它粘贴到浏览器中,它就可以工作了。
跨源身份验证有效:
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 安全性进行身份验证。跨源请求还需要什么?
使用的 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() {
}
}
通过 CORS 非 GET
请求自动在浏览器中发送预检请求。您应该在 HTTP 服务器上允许 OPTIONS
方法,并在 CORS 中允许 headers 来处理这些请求。您的服务器应该响应 CORS allow headers 和 200 ok
对 preflights 的空响应 body。
根据您的评论,问题可能是由您的自定义 x-auth-token
header 引起的,它不是由 OPTIONS
请求发送的,因此您的服务器响应 403 forbidden
.
A preflight call is a call to determine if an action is allowed. It should not require credentials to determine if I can do something, it should only require credentials to actually do it.
我同意 Ryan 的观点,你不应该通过选项检查身份验证 headers。
对于预检 CORS 请求,您需要注意 OPTIONS
请求中不会发送凭据。如果后者在其响应中发回正确的 CORS headers,则使用凭据调用目标请求。这就是为什么你有 403 状态码...
所以你需要调整你的 CORS 过滤器,不要尝试验证这个 OPTIONS
请求。
除了前面的答案,这个 link 可以帮助您解决问题:https://templth.wordpress.com/2014/11/12/understanding-and-using-cors/。