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.servlet.config.annotation; 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 * @author Sam Brannen 030 * @since 4.2 031 * @see CorsConfiguration 032 * @see CorsRegistry 033 */ 034public class CorsRegistration { 035 036 private final String pathPattern; 037 038 private final CorsConfiguration config; 039 040 041 public CorsRegistration(String pathPattern) { 042 this.pathPattern = pathPattern; 043 // Same implicit default values as the @CrossOrigin annotation + allows simple methods 044 this.config = new CorsConfiguration().applyPermitDefaultValues(); 045 } 046 047 048 /** 049 * The list of allowed origins that be specific origins, e.g. 050 * {@code "https://domain1.com"}, or {@code "*"} for all origins. 051 * <p>A matched origin is listed in the {@code Access-Control-Allow-Origin} 052 * response header of preflight actual CORS requests. 053 * <p>By default, all origins are allowed. 054 * <p><strong>Note:</strong> CORS checks use values from "Forwarded" 055 * (<a href="https://tools.ietf.org/html/rfc7239">RFC 7239</a>), 056 * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, 057 * if present, in order to reflect the client-originated address. 058 * Consider using the {@code ForwardedHeaderFilter} in order to choose from a 059 * central place whether to extract and use, or to discard such headers. 060 * See the Spring Framework reference for more on this filter. 061 */ 062 public CorsRegistration allowedOrigins(String... origins) { 063 this.config.setAllowedOrigins(Arrays.asList(origins)); 064 return this; 065 } 066 067 068 /** 069 * Set the HTTP methods to allow, e.g. {@code "GET"}, {@code "POST"}, etc. 070 * <p>The special value {@code "*"} allows all methods. 071 * <p>By default "simple" methods {@code GET}, {@code HEAD}, and {@code POST} 072 * are allowed. 073 */ 074 public CorsRegistration allowedMethods(String... methods) { 075 this.config.setAllowedMethods(Arrays.asList(methods)); 076 return this; 077 } 078 079 /** 080 * Set the list of headers that a pre-flight request can list as allowed 081 * for use during an actual request. 082 * <p>The special value {@code "*"} may be used to allow all headers. 083 * <p>A header name is not required to be listed if it is one of: 084 * {@code Cache-Control}, {@code Content-Language}, {@code Expires}, 085 * {@code Last-Modified}, or {@code Pragma} as per the CORS spec. 086 * <p>By default all headers are allowed. 087 */ 088 public CorsRegistration allowedHeaders(String... headers) { 089 this.config.setAllowedHeaders(Arrays.asList(headers)); 090 return this; 091 } 092 093 /** 094 * Set the list of response headers other than "simple" headers, i.e. 095 * {@code Cache-Control}, {@code Content-Language}, {@code Content-Type}, 096 * {@code Expires}, {@code Last-Modified}, or {@code Pragma}, that an 097 * actual response might have and can be exposed. 098 * <p>The special value {@code "*"} allows all headers to be exposed for 099 * non-credentialed requests. 100 * <p>By default this is not set. 101 */ 102 public CorsRegistration exposedHeaders(String... headers) { 103 this.config.setExposedHeaders(Arrays.asList(headers)); 104 return this; 105 } 106 107 /** 108 * Whether the browser should send credentials, such as cookies along with 109 * cross domain requests, to the annotated endpoint. The configured value is 110 * set on the {@code Access-Control-Allow-Credentials} response header of 111 * preflight requests. 112 * <p><strong>NOTE:</strong> Be aware that this option establishes a high 113 * level of trust with the configured domains and also increases the surface 114 * attack of the web application by exposing sensitive user-specific 115 * information such as cookies and CSRF tokens. 116 * <p>By default this is not set in which case the 117 * {@code Access-Control-Allow-Credentials} header is also not set and 118 * credentials are therefore not allowed. 119 */ 120 public CorsRegistration allowCredentials(boolean allowCredentials) { 121 this.config.setAllowCredentials(allowCredentials); 122 return this; 123 } 124 125 /** 126 * Configure how long in seconds the response from a pre-flight request 127 * can be cached by clients. 128 * <p>By default this is set to 1800 seconds (30 minutes). 129 */ 130 public CorsRegistration maxAge(long maxAge) { 131 this.config.setMaxAge(maxAge); 132 return this; 133 } 134 135 protected String getPathPattern() { 136 return this.pathPattern; 137 } 138 139 protected CorsConfiguration getCorsConfiguration() { 140 return this.config; 141 } 142 143}