001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.reactive.config; 018 019import java.util.Arrays; 020 021import org.springframework.web.cors.CorsConfiguration; 022 023/** 024 * Assists with the creation of a {@link CorsConfiguration} instance for a given 025 * URL path pattern. 026 * 027 * @author Sebastien Deleuze 028 * @author Rossen Stoyanchev 029 * @since 5.0 030 * @see CorsConfiguration 031 * @see CorsRegistry 032 */ 033public class CorsRegistration { 034 035 private final String pathPattern; 036 037 private final CorsConfiguration config; 038 039 040 public CorsRegistration(String pathPattern) { 041 this.pathPattern = pathPattern; 042 // Same implicit default values as the @CrossOrigin annotation + allows simple methods 043 this.config = new CorsConfiguration().applyPermitDefaultValues(); 044 } 045 046 047 /** 048 * The list of allowed origins that be specific origins, e.g. 049 * {@code "https://domain1.com"}, or {@code "*"} for all origins. 050 * <p>A matched origin is listed in the {@code Access-Control-Allow-Origin} 051 * response header of preflight actual CORS requests. 052 * <p>By default all origins are allowed. 053 * <p><strong>Note:</strong> CORS checks use values from "Forwarded" 054 * (<a href="https://tools.ietf.org/html/rfc7239">RFC 7239</a>), 055 * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, 056 * if present, in order to reflect the client-originated address. 057 * Consider using the {@code ForwardedHeaderFilter} in order to choose from a 058 * central place whether to extract and use, or to discard such headers. 059 * See the Spring Framework reference for more on this filter. 060 */ 061 public CorsRegistration allowedOrigins(String... origins) { 062 this.config.setAllowedOrigins(Arrays.asList(origins)); 063 return this; 064 } 065 066 /** 067 * Set the HTTP methods to allow, e.g. {@code "GET"}, {@code "POST"}, etc. 068 * <p>The special value {@code "*"} allows all methods. 069 * <p>By default "simple" methods {@code GET}, {@code HEAD}, and {@code POST} 070 * are allowed. 071 */ 072 public CorsRegistration allowedMethods(String... methods) { 073 this.config.setAllowedMethods(Arrays.asList(methods)); 074 return this; 075 } 076 077 /** 078 * Set the list of headers that a pre-flight request can list as allowed 079 * for use during an actual request. 080 * <p>The special value {@code "*"} may be used to allow all headers. 081 * <p>A header name is not required to be listed if it is one of: 082 * {@code Cache-Control}, {@code Content-Language}, {@code Expires}, 083 * {@code Last-Modified}, or {@code Pragma} as per the CORS spec. 084 * <p>By default all headers are allowed. 085 */ 086 public CorsRegistration allowedHeaders(String... headers) { 087 this.config.setAllowedHeaders(Arrays.asList(headers)); 088 return this; 089 } 090 091 /** 092 * Set the list of response headers other than "simple" headers, i.e. 093 * {@code Cache-Control}, {@code Content-Language}, {@code Content-Type}, 094 * {@code Expires}, {@code Last-Modified}, or {@code Pragma}, that an 095 * actual response might have and can be exposed. 096 * <p>The special value {@code "*"} allows all headers to be exposed for 097 * non-credentialed requests. 098 * <p>By default this is not set. 099 */ 100 public CorsRegistration exposedHeaders(String... headers) { 101 this.config.setExposedHeaders(Arrays.asList(headers)); 102 return this; 103 } 104 105 /** 106 * Whether the browser should send credentials, such as cookies along with 107 * cross domain requests, to the annotated endpoint. The configured value is 108 * set on the {@code Access-Control-Allow-Credentials} response header of 109 * preflight requests. 110 * <p><strong>NOTE:</strong> Be aware that this option establishes a high 111 * level of trust with the configured domains and also increases the surface 112 * attack of the web application by exposing sensitive user-specific 113 * information such as cookies and CSRF tokens. 114 * <p>By default this is not set in which case the 115 * {@code Access-Control-Allow-Credentials} header is also not set and 116 * credentials are therefore not allowed. 117 */ 118 public CorsRegistration allowCredentials(boolean allowCredentials) { 119 this.config.setAllowCredentials(allowCredentials); 120 return this; 121 } 122 123 /** 124 * Configure how long in seconds the response from a pre-flight request 125 * can be cached by clients. 126 * <p>By default this is set to 1800 seconds (30 minutes). 127 */ 128 public CorsRegistration maxAge(long maxAge) { 129 this.config.setMaxAge(maxAge); 130 return this; 131 } 132 133 protected String getPathPattern() { 134 return this.pathPattern; 135 } 136 137 protected CorsConfiguration getCorsConfiguration() { 138 return this.config; 139 } 140 141}