Aop
JSON参数输出优化 Validation
验证代码 controller
, entity
模版生成 aop
, filter
, interceptor
, controller
, param
, vo
代码目录结构 XssFilter
, XssHttpServletRequestWrapper
, XssJacksonDeserializer
, XssJacksonSerializer
SpringBootPlusCorsProperties
JacksonConfig
LogAop
, RequestPathFilter
, ShiroConfig
spring-boot Fastjson hutool commons-text
CORS:Cross-Origin Resource Sharing
使用 Spring
提供的 CorsFilter
过滤器实现跨域配置
io.geekidea.springbootplus.core.config.SpringBootPlusConfig
/** * CORS跨域设置 * * @return */ @Bean public FilterRegistrationBean corsFilter(SpringBootPlusCorsProperties corsProperties) { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); // 跨域配置 corsConfiguration.setAllowedOrigins(corsProperties.getAllowedOrigins()); corsConfiguration.setAllowedHeaders(corsProperties.getAllowedHeaders()); corsConfiguration.setAllowedMethods(corsProperties.getAllowedMethods()); corsConfiguration.setAllowCredentials(corsProperties.isAllowCredentials()); corsConfiguration.setExposedHeaders(corsProperties.getExposedHeaders()); source.registerCorsConfiguration(corsProperties.getPath(), corsConfiguration); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(Ordered.HIGHEST_PRECEDENCE); bean.setEnabled(corsProperties.isEnable()); return bean; }
配置文件类: io.geekidea.springbootplus.core.properties.SpringBootPlusCorsProperties
spring-boot-plus: ############################ CORS start ############################ # CORS跨域配置,默认允许跨域 cors: # 是否启用跨域,默认启用 enable: true # CORS过滤的路径,默认:/** path: /** # 允许访问的源 allowed-origins: '*' # 允许访问的请求头 allowed-headers: x-requested-with,content-type,token # 是否允许发送cookie allow-credentials: true # 允许访问的请求方式 allowed-methods: OPTION,GET,POST # 允许响应的头 exposed-headers: token # 该响应的有效时间默认为30分钟,在有效时间内,浏览器无须为同一请求再次发起预检请求 max-age: 1800 ############################ CORS end ##############################
XSS:Cross Site Scripting
将参数中的特殊字符进行转换
<script>alert(1);</script>
<script>alert(1);</script>
使用 commons-text
包中的 StringEscapeUtils.escapeHtml4();
方法
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.8</version> </dependency>
对 HttpServletRequest
对象的请求参数进行处理
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { public XssHttpServletRequestWrapper(HttpServletRequest request) { super(request); } @Override public String getQueryString() { String value = super.getQueryString(); return StringEscapeUtils.escapeHtml4(value); } @Override public String getParameter(String name) { String value = super.getParameter(name); return StringEscapeUtils.escapeHtml4(value); } @Override public String[] getParameterValues(String name) { String[] values = super.getParameterValues(name); if (ArrayUtils.isEmpty(values)) { return values; } int length = values.length; String[] escapeValues = new String[length]; for (int i = 0; i < length; i++) { String value = values[i]; escapeValues[i] = StringEscapeUtils.escapeHtml4(value); } return escapeValues; } }
使用 WebFilter
注解,拦截所有请求,过滤请求参数
@Slf4j @WebFilter(filterName = "xssFilter", urlPatterns = "/*", asyncSupported = true) public class XssFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; XssHttpServletRequestWrapper xssHttpServletRequestWrapper = new XssHttpServletRequestWrapper(request); filterChain.doFilter(xssHttpServletRequestWrapper, servletResponse); } }
扫描使用servlet注解的类,启用 XssFilter
@ServletComponentScan
实现Jackson反序列化方法,将参数值转义处理
public class XssJacksonDeserializer extends JsonDeserializer<String> { @Override public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { return StringEscapeUtils.escapeHtml4(jsonParser.getText()); } }
实现Jackson序列化方法,将参数值转义处理
@Slf4j public class XssJacksonSerializer extends JsonSerializer<String> { @Override public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(StringEscapeUtils.escapeHtml4(s)); } }
@Configuration public class JacksonConfig implements WebMvcConfigurer { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { // code... // XSS序列化 simpleModule.addSerializer(String.class, new XssJacksonSerializer()); simpleModule.addDeserializer(String.class, new XssJacksonDeserializer()); // code... } }
实现字符串转义的核心方法:
org.apache.commons.text.StringEscapeUtils
StringEscapeUtils.escapeHtml4();