参数校验注解的实现

/**
 * 请求参数注解处理类
 *
 * @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 = "<|>|\\$|&gt|&lt|&#|/\\*.*\\*/|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);
        }
    }
}

  

posted @ 2022-11-03 20:05  屠城校尉杜  阅读(7)  评论(0编辑  收藏  举报