我们正在开发一个java-spring mvc项目。为了让客户端团队能够连接到我们的服务,我们创建了一个CorsFilter:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException,
IOException {
// populating the header required for CORS
String responseURL = this.corsMap.get(request.getServerName().toString());
response.addHeader(
"Access-Control-Allow-Origin",
(responseURL == null ? "https://default.ourCompany.com" : responseURL));
response.addHeader(
"Access-Control-Allow-Credentials",
"true");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
// CORS "pre-flight" request
response.addHeader(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE");
response.addHeader(
"Access-Control-Allow-Headers",
"X-Requested-With,Origin,Content-Type, Accept");
}
filterChain.doFilter(
request,
response);
}
注意事项:
1)我们允许所有的选项传入请求。
2)我们允许为"Access-Control-Allow-Headers"指定ip(因为"Access-Control-Allow-Credentials"=true要求这样)
3)一个名为corsMap的映射包含所有客户端url和它们到服务器url的映射,如下所示:
10.110.0.55->http://localhost
10.110.0.66->https://some.other.url
现在我们有一个问题:
我们希望使用来自"http://localhost"one_answers"http://some.other.url"的客户端。我们如何才能做到这一点?(这里的问题是只允许一个客户端URL,如果客户端请求可以从多个URL接收-我们将无法确定允许什么)。
对于跨域请求,请求将具有一个"Origin"报头,稍后将与"Access-Control-Allow-Origin"响应报头(我们在上面的过滤器中提供的)匹配。
所以,我认为,编码doFilterInternal
如下应该工作:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException,
IOException {
String clientURL = request.getHeader("Origin");
response.addHeader(
"Access-Control-Allow-Origin",
isInWhileList(clientURL) ? clientUrl : "https://default.ourCompany.com";
...
注意:
最新版本的Spring有一种配置CORS的新方法,它有一个allowedOrigins
方法,可以接受一组白名单url。
您也可以参考Spring Lemon的源代码以获得具体示例。