首先请参考:SpringBoot 之 SpringMVC拦截器从Request中获取参数并解决request的请求流只能读取一次的问题
参考完上面的代码,现在开始编辑SQL注入拦截器,核心功能代码如下:
package com.digipower.erms.interceptor;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ctc.wstx.util.StringUtil;
import com.digipower.erms.annotation.SysLog;
import com.digipower.erms.api.LogRecordService;
import com.digipower.erms.common.cache.RedisUtil;
import com.digipower.erms.common.model.Result;
import com.digipower.erms.domain.LogRecord;
import com.digipower.erms.request.wrapper.SQLInjectionHttpServletRequestWrapper;
import com.digipower.erms.util.HttpContextUtils;
import com.digipower.erms.util.HttpUtils;
import com.digipower.erms.util.SecurityUtils;
/**
* 全局拦截器
*/
public class ErmsInterceptor extends HandlerInterceptorAdapter {
private static final Logger log = LoggerFactory.getLogger(ErmsInterceptor.class);
@Autowired
private LogRecordService service;
@Autowired
SecurityUtils securityUtils;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug("ErmsInterceptor start pre ...");
String method = request.getMethod();
if("POST".equals(method)){
SQLInjectionHttpServletRequestWrapper wrapper = new SQLInjectionHttpServletRequestWrapper(request);
String requestBody = wrapper.getRequestBodyParame();
if(!StringUtils.isEmpty(requestBody)){
//sql注入直接拦截
if(sqlInject(requestBody.toLowerCase())){
// 补全拦截器过滤用户登入信息
if (handler instanceof HandlerMethod) {
HandlerMethod h = (HandlerMethod) handler;
insertLogRecord(h,requestBody);
}
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print(JSON.toJSONString(Result.ok("-3","请求异常").setData("error-message", "参数含有非法攻击字符,已禁止继续访问")));
return false;
}
}
} else {
Enumeration<String> names = request.getParameterNames();
// 请求参数转换JSON 对象
List<Map> container = new ArrayList<Map>();
while(names.hasMoreElements()){
Map<String,String> map = new HashMap<String,String>();
String key = names.nextElement();
String value = request.getParameter(key);
map.put(key, value);
container.add(map);
}
String requestBody = JSON.toJSONString(container);
while(names.hasMoreElements()){
String name = names.nextElement();
String[] values = request.getParameterValues(name);
for(String value: values){
//sql注入直接拦截
if(sqlInject(value.toLowerCase())){
// 补全拦截器过滤用户登入信息
if(handler instanceof HandlerMethod){
HandlerMethod h = (HandlerMethod) handler;
insertLogRecord(h,requestBody);
}
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print(JSON.toJSONString(Result.ok("-3","请求异常").setData("error-message", "参数含有非法攻击字符,已禁止继续访问")));
return false;
}
// 脚本注入XSS
StringEscapeUtils.escapeHtml(value);
StringEscapeUtils.escapeHtml(value);
}
}
}
//TODO
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
super.afterCompletion(request, response, handler, ex);
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
super.afterConcurrentHandlingStarted(request, response, handler);
}
/**
*
* @Title: sqlInject
* @Description: TODO SQL 注入正在表达式(sql 函数关键字过滤)
* @param: @param value
* @param: @return
* @return: boolean
* @throws
*/
public boolean sqlInject(String value){
if(value == null || "".equals(value)){
return false;
}
String regex =".*(select|update|union|and|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|drop|execute|[+]|%).*";
boolean isMatch = Pattern.matches(regex, value);
return isMatch;
}
public void insertLogRecord(HandlerMethod handlerMethod,String queryParame){
LogRecord record = new LogRecord();
SysLog sysLog = handlerMethod.getMethodAnnotation(SysLog.class);
if (sysLog != null) {
// 注解上的描述
record.setLogType(Short.valueOf("-1"));
record.setLogDesc(sysLog.value());
}
String className = handlerMethod.getClass().getName();
String methodName = handlerMethod.getMethod().getName();
record.setClassMethod(className + "." + methodName + "()");
// 请求参数
record.setParames(queryParame);
// 请求地址
HttpServletRequest request = HttpContextUtils.getRequest();
String ip = HttpUtils.getIpAddress(request);
record.setIpAddress(ip);
// 操作用户
String username = securityUtils.getAuthUserPin(request);
record.setUsername(username);
// 创建时间
record.setCreateTime(new Date());
service.insert(record);
}
}
springboot 配置拦截器:
package com.digipower.ucas.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableWebMvc
public class SwaggerConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
// 定义json 转换器
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// TODO Auto-generated method stub
super.configureMessageConverters(converters);
}
@Bean
public Docket buildDocket() {
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> pars = new ArrayList<Parameter>();
tokenPar.name("X-CSRF-TOKEN").description("令牌").modelRef(new ModelRef("string")).parameterType("header")
.required(false).build();
pars.add(tokenPar.build());
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any())
.build().globalOperationParameters(pars).apiInfo(buildApiInf());
}
private ApiInfo buildApiInf() {
return new ApiInfoBuilder().title("深圳市世纪伟图科技开发有限公司 - 城建档案系统").termsOfServiceUrl("http://www.digipower.cn/")
.description("API接口")
.contact(new Contact("digipower", "http://www.digipower.cn/", "digiservices@digipower.com"))
.version("2.0").build();
}
//SQL注入拦截器
@Bean
public ErmsInterceptor sqlInjectInterceptor () {
return new ErmsInterceptor ();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {// 2
registry.addInterceptor(sqlInjectInterceptor());
}
}