Skip to content

Commit

Permalink
🎨 CORS 配置从 OpenAPI starter 迁移到 Web stater 中
Browse files Browse the repository at this point in the history
  • Loading branch information
Hccake committed Jan 31, 2024
1 parent 14364c4 commit 267c9ca
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
* OpenAPI 的自动配置类
Expand Down Expand Up @@ -96,37 +91,6 @@ private Info convertInfo(OpenApiProperties.InfoProperties infoProperties) {
return info;
}

/**
* 允许聚合者对提供者的文档进行跨域访问 解决聚合文档导致的跨域问题
* @return FilterRegistrationBean
*/
@Bean
@ConditionalOnProperty(prefix = OpenApiProperties.PREFIX + ".cors-config", name = "enabled", havingValue = "true")
public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean() {
// 获取 CORS 配置
OpenApiProperties.CorsConfig corsConfig = this.openApiProperties.getCorsConfig();

// 转换 CORS 配置
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(corsConfig.getAllowedOrigins());
corsConfiguration.setAllowedOriginPatterns(corsConfig.getAllowedOriginPatterns());
corsConfiguration.setAllowedMethods(corsConfig.getAllowedMethods());
corsConfiguration.setAllowedHeaders(corsConfig.getAllowedHeaders());
corsConfiguration.setExposedHeaders(corsConfig.getExposedHeaders());
corsConfiguration.setAllowCredentials(corsConfig.getAllowCredentials());
corsConfiguration.setMaxAge(corsConfig.getMaxAge());

// 注册 CORS 配置与资源的映射关系
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(corsConfig.getUrlPattern(), corsConfiguration);

// 注册 CORS 过滤器,设置最高优先级
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);

return bean;
}

/**
* The type Spring doc pageParam configuration.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@

package org.ballcat.autoconfigure.openapi;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

Expand All @@ -32,7 +30,6 @@
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.web.cors.CorsConfiguration;

/**
* @author Hccake 2019/11/1 19:37
Expand Down Expand Up @@ -98,11 +95,6 @@ public class OpenApiProperties {
*/
private Map<String, Object> extensions = null;

/**
* 跨域配置
*/
private CorsConfig corsConfig;

/**
* <p>
* 文档的基础属性信息
Expand Down Expand Up @@ -154,62 +146,4 @@ public static class InfoProperties {

}

/**
* <p>
* 跨域配置,用于文档聚合.
* </p>
*
* @see CorsConfiguration
*/
@Data
public static class CorsConfig {

/**
* 开启 Cors 跨域配置
*/
private boolean enabled = false;

/**
* 跨域对应的 url 匹配规则
*/
private String urlPattern = "/**";

/**
* 允许跨域的源
*/
private List<String> allowedOrigins;

/**
* 允许跨域来源的匹配规则
*/
private List<String> allowedOriginPatterns;

/**
* 允许跨域的方法列表
*/
private List<String> allowedMethods = new ArrayList<>(Collections.singletonList(CorsConfiguration.ALL));

/**
* 允许跨域的头信息
*/
private List<String> allowedHeaders = new ArrayList<>(Collections.singletonList(CorsConfiguration.ALL));

/**
* 额外允许跨域请求方获取的 response header 信息
*/
private List<String> exposedHeaders = new ArrayList<>(Collections.singletonList("traceId"));

/**
* 是否允许跨域发送 Cookie
*/
private Boolean allowCredentials = true;

/**
* CORS 配置缓存时间,用于控制浏览器端是否发起 Option 预检请求。 若配置此参数,在第一次获取到 CORS
* 的配置信息后,在过期时间内,浏览器将直接发出请求,跳过 option 预检
*/
private Long maxAge;

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@
import org.bson.types.ObjectId;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

Expand All @@ -43,6 +47,8 @@
@EnableConfigurationProperties({ WebProperties.class, PageableProperties.class })
public class WebMvcAutoConfiguration {

private final WebProperties webProperties;

@Bean
@ConditionalOnMissingBean
public PageParamArgumentResolver pageParamArgumentResolver(PageableProperties pageableProperties) {
Expand All @@ -51,6 +57,42 @@ public PageParamArgumentResolver pageParamArgumentResolver(PageableProperties pa
pageableProperties.getSortParameterName());
}

/**
* 允许聚合者对提供者的文档进行跨域访问 解决聚合文档导致的跨域问题
* @return FilterRegistrationBean
*/
@Bean
@ConditionalOnProperty(prefix = WebProperties.PREFIX + ".cors-config", name = "enabled", havingValue = "true")
public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean() {
// 获取 CORS 配置
WebProperties.CorsConfig corsConfig = this.webProperties.getCorsConfig();

// 转换 CORS 配置
CorsConfiguration corsConfiguration = getCorsConfiguration(corsConfig);

// 注册 CORS 配置与资源的映射关系
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration(corsConfig.getUrlPattern(), corsConfiguration);

// 注册 CORS 过滤器,设置最高优先级 + 1 (在 traceId 之后)
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE + 1000);

return bean;
}

private static CorsConfiguration getCorsConfiguration(WebProperties.CorsConfig corsConfig) {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedOrigins(corsConfig.getAllowedOrigins());
corsConfiguration.setAllowedOriginPatterns(corsConfig.getAllowedOriginPatterns());
corsConfiguration.setAllowedMethods(corsConfig.getAllowedMethods());
corsConfiguration.setAllowedHeaders(corsConfig.getAllowedHeaders());
corsConfiguration.setExposedHeaders(corsConfig.getExposedHeaders());
corsConfiguration.setAllowCredentials(corsConfig.getAllowCredentials());
corsConfiguration.setMaxAge(corsConfig.getMaxAge());
return corsConfiguration;
}

@RequiredArgsConstructor
@Configuration(proxyBeanMethods = false)
static class CustomWebMvcConfigurer implements WebMvcConfigurer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,89 @@

package org.ballcat.autoconfigure.web.servlet;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.cors.CorsConfiguration;

/**
* @author hccake
*/
@Data
@ConfigurationProperties(prefix = "ballcat.web")
@ConfigurationProperties(prefix = WebProperties.PREFIX)
public class WebProperties {

public static final String PREFIX = "ballcat.web";

/**
* traceId 的 http 头名称
*/
private String traceIdHeaderName = "X-Trace-Id";

/**
* 跨域配置
*/
private CorsConfig corsConfig;

/**
* <p>
* 跨域配置.
* </p>
*
* @see CorsConfiguration
*/
@Data
public static class CorsConfig {

/**
* 开启 Cors 跨域配置
*/
private boolean enabled = false;

/**
* 跨域对应的 url 匹配规则
*/
private String urlPattern = "/**";

/**
* 允许跨域的源
*/
private List<String> allowedOrigins;

/**
* 允许跨域来源的匹配规则
*/
private List<String> allowedOriginPatterns;

/**
* 允许跨域的方法列表
*/
private List<String> allowedMethods = new ArrayList<>(Collections.singletonList(CorsConfiguration.ALL));

/**
* 允许跨域的头信息
*/
private List<String> allowedHeaders = new ArrayList<>(Collections.singletonList(CorsConfiguration.ALL));

/**
* 额外允许跨域请求方获取的 response header 信息
*/
private List<String> exposedHeaders = new ArrayList<>(Collections.singletonList("traceId"));

/**
* 是否允许跨域发送 Cookie
*/
private Boolean allowCredentials = true;

/**
* CORS 配置缓存时间,用于控制浏览器端是否发起 Option 预检请求。 若配置此参数,在第一次获取到 CORS
* 的配置信息后,在过期时间内,浏览器将直接发出请求,跳过 option 预检
*/
private Long maxAge;

}

}

0 comments on commit 267c9ca

Please sign in to comment.