コード例 #1
0
  /**
   * Handles CORS pre-flight request.
   *
   * @param request The {@link HttpServletRequest} object.
   * @param response The {@link HttpServletResponse} object.
   * @param filterChain The {@link FilterChain} object.
   * @throws IOException
   * @throws ServletException
   */
  public void handlePreflightCORS(
      final HttpServletRequest request,
      final HttpServletResponse response,
      final FilterChain filterChain)
      throws IOException, ServletException {
    CORSRequestType requestType = checkRequestType(request);
    if (requestType != CORSRequestType.PRE_FLIGHT) {
      throw new IllegalArgumentException(
          "Expects a HttpServletRequest object of type "
              + CORSRequestType.PRE_FLIGHT.name().toLowerCase());
    }

    final String origin = request.getHeader(CORSFilter.REQUEST_HEADER_ORIGIN);

    // Section 6.2.2
    if (!isOriginAllowed(origin)) {
      handleInvalidCORS(request, response, filterChain);
      return;
    }

    // Section 6.2.3
    String accessControlRequestMethod =
        request.getHeader(CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_METHOD);
    if (accessControlRequestMethod == null
        || (!HTTP_METHODS.contains(accessControlRequestMethod.trim()))) {
      handleInvalidCORS(request, response, filterChain);
      return;
    } else {
      accessControlRequestMethod = accessControlRequestMethod.trim();
    }

    // Section 6.2.4
    String accessControlRequestHeadersHeader =
        request.getHeader(CORSFilter.REQUEST_HEADER_ACCESS_CONTROL_REQUEST_HEADERS);
    List<String> accessControlRequestHeaders = new LinkedList<String>();
    if (accessControlRequestHeadersHeader != null
        && !accessControlRequestHeadersHeader.trim().isEmpty()) {
      String[] headers = accessControlRequestHeadersHeader.trim().split(",");
      for (String header : headers) {
        accessControlRequestHeaders.add(header.trim().toLowerCase());
      }
    }

    // Section 6.2.5
    if (!allowedHttpMethods.contains(accessControlRequestMethod)) {
      handleInvalidCORS(request, response, filterChain);
      return;
    }

    // Section 6.2.6
    if (!accessControlRequestHeaders.isEmpty()) {
      for (String header : accessControlRequestHeaders) {
        if (!allowedHttpHeaders.contains(header)) {
          handleInvalidCORS(request, response, filterChain);
          return;
        }
      }
    }

    // Section 6.2.7
    if (supportsCredentials) {
      response.addHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, origin);
      response.addHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    } else {
      if (anyOriginAllowed) {
        response.addHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, "*");
      } else {
        response.addHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, origin);
      }
    }

    // Section 6.2.8
    if (preflightMaxAge > 0) {
      response.addHeader(
          CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_MAX_AGE, String.valueOf(preflightMaxAge));
    }

    // Section 6.2.9
    response.addHeader(
        CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_METHODS, accessControlRequestMethod);

    // Section 6.2.10
    if ((allowedHttpHeaders != null) && (!allowedHttpHeaders.isEmpty())) {
      response.addHeader(
          CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, join(allowedHttpHeaders, ","));
    }

    // Do not forward the request down the filter chain.
  }
コード例 #2
0
  /**
   * Handles a CORS request of type {@link CORSRequestType}.SIMPLE.
   *
   * @param request The {@link HttpServletRequest} object.
   * @param response The {@link HttpServletResponse} object.
   * @param filterChain The {@link FilterChain} object.
   * @throws IOException
   * @throws ServletException
   * @see <a href="http://www.w3.org/TR/cors/#resource-requests">Simple Cross-Origin Request, Actual
   *     Request, and Redirects</a>
   */
  public void handleSimpleCORS(
      final HttpServletRequest request,
      final HttpServletResponse response,
      final FilterChain filterChain)
      throws IOException, ServletException {
    CORSFilter.CORSRequestType requestType = checkRequestType(request);
    if (!(requestType == CORSFilter.CORSRequestType.SIMPLE
        || requestType == CORSFilter.CORSRequestType.ACTUAL)) {
      String message =
          "Expects a HttpServletRequest object of type "
              + CORSFilter.CORSRequestType.SIMPLE
              + " or "
              + CORSFilter.CORSRequestType.ACTUAL;
      throw new IllegalArgumentException(message);
    }

    final String origin = request.getHeader(CORSFilter.REQUEST_HEADER_ORIGIN);
    final String method = request.getMethod();

    // Section 6.1.2
    if (!isOriginAllowed(origin)) {
      handleInvalidCORS(request, response, filterChain);
      return;
    }

    if (!allowedHttpMethods.contains(method)) {
      handleInvalidCORS(request, response, filterChain);
      return;
    }

    // Section 6.1.3
    // Add a single Access-Control-Allow-Origin header.
    if (anyOriginAllowed && !supportsCredentials) {
      // If resource doesn't support credentials and if any origin is
      // allowed
      // to make CORS request, return header with '*'.
      response.addHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, "*");
    } else {
      // If the resource supports credentials add a single
      // Access-Control-Allow-Origin header, with the value of the Origin
      // header as value.
      response.addHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN, origin);
    }
    // Section 6.1.3
    // If the resource supports credentials, add a single
    // Access-Control-Allow-Credentials header with the case-sensitive
    // string "true" as value.
    if (supportsCredentials) {
      response.addHeader(CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    }

    // Section 6.1.4
    // If the list of exposed headers is not empty add one or more
    // Access-Control-Expose-Headers headers, with as values the header
    // field names given in the list of exposed headers.
    if ((exposedHeaders != null) && (exposedHeaders.size() > 0)) {
      String exposedHeadersString = join(exposedHeaders, ",");
      response.addHeader(
          CORSFilter.RESPONSE_HEADER_ACCESS_CONTROL_EXPOSE_HEADERS, exposedHeadersString);
    }

    // Forward the request down the filter chain.
    filterChain.doFilter(request, response);
  }