Cors filter for localhost and staging url

2019-09-07 02:11发布

问题:

We are developing a java-spring mvc project. In order for the client team to be able to connect to our services we created a 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);
}

Things to note:

1) we allow all for any OPTIONS incoming request.

2) We allow specific ip for "Access-Control-Allow-Headers" (since "Access-Control-Allow-Credentials"=true requires so)

3) a map called corsMap contains all the client urls and their mapping to server urls, like so:

10.110.0.55->http://localhost
10.110.0.66->https://some.other.url

Now we have a problem:

We would like to use clients from "http://localhost" AND from "http://some.other.url". how can we achieve that? (the problem here is that only a single client URL is allowed, and if the clients request can be received from multiple URL - we wont be able to determine what to allow).

回答1:

For cross domain requests, the request would be having an "Origin" header, which would later get matched with the "Access-Control-Allow-Origin" response header (that we provide in the above filter).

So, I think, coding the doFilterInternal as below should work:

@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";
    ...

Note:

The latest version of Spring has a new way to configure CORS, which has an allowedOrigins method, which can take an array of whitelisted URLs.

You can also refer to Spring Lemon's source code for a concrete example.