/**
* 请求参数注解处理类
*
* @author d
* @since 2019/2/20 14:32
*/
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
int flag = 0;
for (HttpMessageConverter converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
break;
}
flag++;
}
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue,
SerializerFeature.QuoteFieldNames);
converter.setFastJsonConfig(config);
converters.add(flag, converter);
converters.removeIf(type -> type instanceof MappingJackson2HttpMessageConverter);
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(MediaType.TEXT_HTML);
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
converter.setSupportedMediaTypes(supportedMediaTypes);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(getHttpsCheckInterceptor()).addPathPatterns("/**");
registry.addInterceptor(getParamCheckInterceptor()).addPathPatterns("/**");
}
/**
* 获取https过滤拦截器
*
* @return https过滤拦截器
*/
@Bean
public HttpsCheckInterceptor getHttpsCheckInterceptor() {
return new HttpsCheckInterceptor();
}
/**
* 获取参数过滤拦截器
*
* @return 参数过滤拦截器
*/
@Bean
public ParamCheckInterceptor getParamCheckInterceptor() {
return new ParamCheckInterceptor();
}
}
/**
* 参数过滤拦截器
*
* @author d
* @since 2019/07/02
*/
public class ParamCheckInterceptor implements HandlerInterceptor {
private static final Logger LOG = LoggerFactory.getLogger(ParamCheckInterceptor.class);
private static final String XSS_PATTERN = "((<.+>)|(/\\*.*/))+";
private static final String XSS_PATTERN2 = "<|>|\\$|>|<|&#|/\\*.*\\*/|vbscript:|javascript:|=\\s*[\\[{\"']";
private static Pattern pattern = Pattern.compile(XSS_PATTERN);
private static Pattern pattern2 = Pattern.compile(XSS_PATTERN2);
private static final String TOO_LONG = "maybe risky param value-too long:";
private static final String API00001 = "API00001";
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exception) throws HwPayException {
LOG.info("afterCompletion");
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView mav) throws HwPayException {
LOG.info("postHandle");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws HwPayException {
// defect 6911012
if (request == null) {
throw new HwPayException(API00001);
}
Enumeration tempEnumRation = request.getParameterNames();
while (tempEnumRation.hasMoreElements()) {
Object obj = tempEnumRation.nextElement();
if (obj instanceof String) {
String paramName = (String) obj;
if (request.getParameter(paramName) != null) {
validData(request, paramName);
}
}
}
return true;
}
/**
* 请求数据校验
*
* @param request 响应request消息
* @param paramName 参数名称
* @throws HwPayException 异常
*/
private void validData(HttpServletRequest request, String paramName) throws HwPayException {
String paramValue = StringUtils.trimToEmpty(request.getParameter(paramName));
// 参数值为空,直接返回
if (StringUtils.isBlank(paramValue)) {
return;
}
// 为防止DDOS攻击,先校验长度,后进行正则判定
if (ParamLengthEnum.containsCode(paramName) && paramValue.length() > ParamLengthEnum.getLength(paramName)) {
LOG.info(TOO_LONG, paramName, ":", paramValue);
throw new HwPayException(API00001);
}
// 默认校验
validDefaultAndKeyInfo(request, paramName, paramValue);
// 正则校验
validPattern(paramName, paramValue);
}
/**
* 默认校验
*
* @param request 请求信息
* @param paramName 参数名称
* @param paramValue 参数值
* @throws HwPayException 支付异常
*/
private void validDefaultAndKeyInfo(HttpServletRequest request, String paramName,
String paramValue) throws HwPayException {
if (paramName.equalsIgnoreCase("keyinfo") && request.getServletPath().equals("/uploadKey.htm")) {
if (paramValue.length() > 20480) {
LOG.info(TOO_LONG, paramName);
throw new HwPayException(API00001);
}
} else {
if (paramValue.length() > ParamLengthEnum.DEFAULT_LENGTH.getLength()) {
LOG.info(TOO_LONG, paramName, ":", paramValue);
throw new HwPayException(API00001);
}
}
}
/**
* 正则校验
*
* @param paramName 参数名称
* @param paramValue 参数值
* @throws HwPayException 异常
*/
private void validPattern(String paramName, String paramValue) throws HwPayException {
if ((pattern.matcher(paramValue).find() || pattern2.matcher(paramValue).find())
&& !PatternValidEnum.containsCode(paramName)) {
LOG.info("maybe risky param value:", paramValue, " for:", paramName);
throw new HwPayException(API00001);
}
}
}