001/* 002 * Copyright 2012-2018 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 * http://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.boot.actuate.autoconfigure.endpoint.web; 018 019import java.time.Duration; 020import java.time.temporal.ChronoUnit; 021import java.util.ArrayList; 022import java.util.List; 023 024import org.springframework.boot.context.properties.ConfigurationProperties; 025import org.springframework.boot.context.properties.PropertyMapper; 026import org.springframework.boot.convert.DurationUnit; 027import org.springframework.util.CollectionUtils; 028import org.springframework.web.cors.CorsConfiguration; 029 030/** 031 * Configuration properties for web endpoints' CORS support. 032 * 033 * @author Andy Wilkinson 034 * @since 2.0.0 035 */ 036@ConfigurationProperties(prefix = "management.endpoints.web.cors") 037public class CorsEndpointProperties { 038 039 /** 040 * Comma-separated list of origins to allow. '*' allows all origins. When not set, 041 * CORS support is disabled. 042 */ 043 private List<String> allowedOrigins = new ArrayList<>(); 044 045 /** 046 * Comma-separated list of methods to allow. '*' allows all methods. When not set, 047 * defaults to GET. 048 */ 049 private List<String> allowedMethods = new ArrayList<>(); 050 051 /** 052 * Comma-separated list of headers to allow in a request. '*' allows all headers. 053 */ 054 private List<String> allowedHeaders = new ArrayList<>(); 055 056 /** 057 * Comma-separated list of headers to include in a response. 058 */ 059 private List<String> exposedHeaders = new ArrayList<>(); 060 061 /** 062 * Whether credentials are supported. When not set, credentials are not supported. 063 */ 064 private Boolean allowCredentials; 065 066 /** 067 * How long the response from a pre-flight request can be cached by clients. If a 068 * duration suffix is not specified, seconds will be used. 069 */ 070 @DurationUnit(ChronoUnit.SECONDS) 071 private Duration maxAge = Duration.ofSeconds(1800); 072 073 public List<String> getAllowedOrigins() { 074 return this.allowedOrigins; 075 } 076 077 public void setAllowedOrigins(List<String> allowedOrigins) { 078 this.allowedOrigins = allowedOrigins; 079 } 080 081 public List<String> getAllowedMethods() { 082 return this.allowedMethods; 083 } 084 085 public void setAllowedMethods(List<String> allowedMethods) { 086 this.allowedMethods = allowedMethods; 087 } 088 089 public List<String> getAllowedHeaders() { 090 return this.allowedHeaders; 091 } 092 093 public void setAllowedHeaders(List<String> allowedHeaders) { 094 this.allowedHeaders = allowedHeaders; 095 } 096 097 public List<String> getExposedHeaders() { 098 return this.exposedHeaders; 099 } 100 101 public void setExposedHeaders(List<String> exposedHeaders) { 102 this.exposedHeaders = exposedHeaders; 103 } 104 105 public Boolean getAllowCredentials() { 106 return this.allowCredentials; 107 } 108 109 public void setAllowCredentials(Boolean allowCredentials) { 110 this.allowCredentials = allowCredentials; 111 } 112 113 public Duration getMaxAge() { 114 return this.maxAge; 115 } 116 117 public void setMaxAge(Duration maxAge) { 118 this.maxAge = maxAge; 119 } 120 121 public CorsConfiguration toCorsConfiguration() { 122 if (CollectionUtils.isEmpty(this.allowedOrigins)) { 123 return null; 124 } 125 PropertyMapper map = PropertyMapper.get(); 126 CorsConfiguration configuration = new CorsConfiguration(); 127 map.from(this::getAllowedOrigins).to(configuration::setAllowedOrigins); 128 map.from(this::getAllowedHeaders).whenNot(CollectionUtils::isEmpty) 129 .to(configuration::setAllowedHeaders); 130 map.from(this::getAllowedMethods).whenNot(CollectionUtils::isEmpty) 131 .to(configuration::setAllowedMethods); 132 map.from(this::getExposedHeaders).whenNot(CollectionUtils::isEmpty) 133 .to(configuration::setExposedHeaders); 134 map.from(this::getMaxAge).whenNonNull().as(Duration::getSeconds) 135 .to(configuration::setMaxAge); 136 map.from(this::getAllowCredentials).whenNonNull() 137 .to(configuration::setAllowCredentials); 138 return configuration; 139 } 140 141}