springboot配置拦截器,在拦截器中获取@RequestBody注解参数和post请求参数以及get请求参数

5 篇文章 1 订阅

1.配置拦截器

package com.jy.gxw.config.interceptor;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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 com.jy.common.base.event.IEventService;
import com.jy.common.interceptor.EventInterceptor;

/**
 * 系统中的拦截器配置
 * 
 * @author ShuoYuan
 *
 */
@Configuration
public class InterceptorConfigurer extends WebMvcConfigurerAdapter {
	@Autowired
	private IEventService eventService;

	/**
	 *      * 配置静态资源      
	 */

	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
		registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/");
		super.addResourceHandlers(registry);
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// addPathPatterns 用于添加拦截规则
		// excludePathPatterns 用于排除拦截
		// 地址拦截器
		registry.addInterceptor(new SessionInterceptor())
		.addPathPatterns("/**")
		.excludePathPatterns("/user/login") // 登录页
		.excludePathPatterns("/api/code/get/pageCode");// 登陆验证码

		super.addInterceptors(registry);
		// 用户操作日志拦截器
		registry.addInterceptor(new EventInterceptor(eventService));

	}

}

package com.jy.gxw.config.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.jy.gxw.util.JSONUtils;

/**
 * Created by 20160216 on 2018/2/8.
 */
public class SessionInterceptor extends HandlerInterceptorAdapter {
	private Logger logger = LoggerFactory.getLogger(SessionInterceptor.class);

	// 拦截前处理
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
		System.out.println("经过拦截器拦截前处理啦。。。。。");
		try {
			RequestWrapper requestWrapper = new RequestWrapper(request);
			// 获取@RequestBody注解参数和post请求参数
			String body = requestWrapper.getBody();
			System.out.println("拦截器输出body:" + body);
			System.out.println("uri=" + request.getRequestURI());
			// 获取get请求参数
			Map<String, String[]> ParameterMap = request.getParameterMap();
			System.out.println("参数个数:" + ParameterMap.size());
			Map reqMap = new HashMap();
			Set<Map.Entry<String, String[]>> entry = ParameterMap.entrySet();
			Iterator<Map.Entry<String, String[]>> it = entry.iterator();
			while (it.hasNext()) {
				Map.Entry<String, String[]> me = it.next();
				String key = me.getKey();
				String value = me.getValue()[0];
				reqMap.put(key, value);
			}
			String queryString = JSONUtils.JsonToString(JSONUtils.MapToJson(reqMap));
			System.out.println(queryString);
			// 不做拦截的地址
			if (request.getRequestURI().equals("/api/code/get/pageCode")) {
				return true;
			}
			// 验证session是否存在
			Object obj = request.getSession().getAttribute("_session_user");
			if (obj == null) {
				response.sendRedirect("/user/login_view");//重定向
				return false;
			}
			return true;
		} catch (Exception e) {
			logger.error("权限判断出错", e);
		}
		return false;
	}

	// 拦截后处理
	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
			ModelAndView modelAndView) throws Exception {

	}

	// 全部完成后处理
	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object o, Exception e) throws Exception {

	}
}

package com.jy.gxw.config.interceptor;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;

public class RequestWrapper extends HttpServletRequestWrapper {
    private final String body;

    public RequestWrapper(HttpServletRequest request) {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {

        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        body = stringBuilder.toString();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {
            }
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream;

    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }

    public String getBody() {
        return this.body;
    }

}
package com.jy.gxw.util;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


public class JSONUtils {
    /**
     * Bean对象转JSON
     * 
     * @param object
     * @param dataFormatString
     * @return
     */
    public static String beanToJson(Object object, String dataFormatString) {
        if (object != null) {
            if (StringUtils.isEmpty(dataFormatString)) {
                return JSONObject.toJSONString(object);
            }
            return JSON.toJSONStringWithDateFormat(object, dataFormatString);
        } else {
            return null;
        }
    }

    /**
     * Bean对象转JSON
     * 
     * @param object
     * @return
     */
    public static String beanToJson(Object object) {
        if (object != null) {
            return JSON.toJSONString(object);
        } else {
            return null;
        }
    }

    /**
     * String转JSON字符串
     * 
     * @param key
     * @param value
     * @return
     */
    public static String stringToJsonByFastjson(String key, String value) {
        if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) {
            return null;
        }
        Map<String, String> map = new HashMap<String, String>();
        map.put(key, value);
        return beanToJson(map, null);
    }

    /**
     * 将json字符串转换成对象
     * 
     * @param json
     * @param clazz
     * @return
     */
    public static Object jsonToBean(String json, Object clazz) {
        if (StringUtils.isEmpty(json) || clazz == null) {
            return null;
        }
        return JSON.parseObject(json, clazz.getClass());
    }

    /**
     * json字符串转map
     * 
     * @param json
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> jsonToMap(String json) {
        if (StringUtils.isEmpty(json)) {
            return null;
        }
        return JSON.parseObject(json, Map.class);
    }
    
    public static JSONObject MapToJson(Map m){
    	JSONObject json = new JSONObject(m);
    	return json;
    }
    
    public static String JsonToString(JSONObject json){
    	return json.toJSONString();
    }
    
    
}

package com.jy.gxw.config.filter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;

import java.util.List;


import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.jy.gxw.config.interceptor.RequestWrapper;

/**
 * 
 * 非法字符过滤器(防SQL注入,防XSS漏洞)
 * 
 * 
 */
public class XssFilter implements Filter {
	private static final Logger logger = LogManager.getLogger(XssFilter.class);

	/**
	 * 排除部分URL不做过滤
	 */
	private List<String> excludeUrls = new ArrayList<String>();

	/**
	 * 公告新增、修改用到富文本,对标签进行转义
	 */
	private List<String> noticeUrls = new ArrayList<String>();

	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		logger.info("================进入过滤器======================");
		HttpServletResponse response = (HttpServletResponse) arg1;
		ServletRequest req = null;
        if(arg0 instanceof HttpServletRequest) {
        	req = new RequestWrapper((HttpServletRequest) arg0);
        	// 获取@RequestBody注解参数和post请求参数
        	String body = ((RequestWrapper) req).getBody();
        	System.out.println("过滤器输出body:" + body);
    		HttpServletRequest req1 = (HttpServletRequest) req;
    		String pathInfo = req1.getPathInfo() == null ? "" : req1.getPathInfo();
    		String url = req1.getServletPath() + pathInfo;
    		String uri = req1.getRequestURI();
    		boolean isNoticeUrl = false;
    		// 排除部分URL不做过滤。
    		for (String str : excludeUrls) {
    			if (uri.indexOf(str) >= 0) {
    				logger.info("该URL不作校验:" + url);
    				arg2.doFilter(req, response);
    				return;
    			}
    		}
    		for (String st : noticeUrls) {
    			if (uri.indexOf(st) >= 0) {
    				isNoticeUrl = true;
    				break;
    			}
    		}
    		List<String> ll=getvalue(body);
    		// 获取请求所有参数值,校验防止SQL注入,防止XSS漏洞
    		if(ll!=null){
    		for(String ss:ll) {
    			// 校验是否存在SQL注入信息
    			if (checkSQLInject(ss, url)) {
    				errorResponse(response, ss);
    				return;
    			}
    		}}
        }
        if(req == null) {
        	arg2.doFilter(arg0, response);
        } else {
        	arg2.doFilter(req, response);
        }
	}
    public  List<String> getvalue(String str){
    	int len=str.length();
    	if(len>5){
    		List<String> l=new ArrayList<String>();
        	for(int i=0;i<len;i++){
        		if(str.charAt(i)==':'){
        			i++;
        			if(str.charAt(i)=='"'){
        				int ii=str.indexOf('"', i+1);
        				l.add(str.substring(i+1, ii));
        				i=ii;
        			}
        		}
        	}
        	return l;
    	}
    	else return null;	
    }
	private void errorResponse(HttpServletResponse response, String paramvalue) throws IOException {
		String warning = "输入项中不能包含非法字符。";

		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();

		out.println("{\"httpCode\":\"-9998\",\"msg\":\"" + warning + "\", \"输入值\": \"" +paramvalue + "\"}");
		out.flush();
		out.close();
	}

	public void destroy() {
	}

	public void init(FilterConfig filterconfig1) throws ServletException {
		// 读取文件
		String path = XssFilter.class.getResource("/").getFile();
		excludeUrls = readFile(path + "xssWhite.txt");
		noticeUrls.add("notice!saveNotice");
		noticeUrls.add("notice!updateNoticeById");
	}

	/**
	 * 读取白名单
	 * 
	 * @param fileName
	 * @return
	 */
	private List<String> readFile(String fileName) {
		List<String> list = new ArrayList<String>();
		BufferedReader reader = null;
		FileInputStream fis = null;
		try {
			File f = new File(fileName);
			if (f.isFile() && f.exists()) {
				fis = new FileInputStream(f);
				reader = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
				String line;
				while ((line = reader.readLine()) != null) {
					if (!"".equals(line)) {
						list.add(line);
					}
				}
			}
		} catch (Exception e) {
			logger.error("readFile", e);
		} finally {
			try {
				if (reader != null) {
					reader.close();
				}
			} catch (IOException e) {
				logger.error("InputStream关闭异常", e);
			}
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException e) {
				logger.error("FileInputStream关闭异常", e);
			}
		}
		return list;
	}

	private String xssEncode(String s) {
		if (s == null || s.isEmpty()) {
			return s;
		}
		/*s.replaceAll("||", "");
		s.replaceAll("|", "");
		s.replaceAll(regex, replacement)*/
		StringBuilder sb = new StringBuilder(s.length() + 16);
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			switch (c) {
			case '>':
				sb.append('>');// 全角大于号
				break;
			case '<':
				sb.append('<');// 全角小于号
				break;
			case '\'':
				sb.append('‘');// 全角单引号
				break;
			case '\"':
				sb.append('“');// 全角双引号
				break;
			case '&':
				sb.append('&');// 全角
				break;
			case '\\':
				sb.append('\');// 全角斜线
				break;
			case '#':
				sb.append('#');// 全角井号
				break;
			case '(':
				sb.append('(');//
				break;
			case ')':
				sb.append(')');//
				break;
			default:
				sb.append(c);
				break;
			}
		}
		return sb.toString();
	}

	/**
	 * 
	 * 检查是否存在非法字符,防止SQL注入
	 * 
	 * @param str
	 *            被检查的字符串
	 * @return ture-字符串中存在非法字符,false-不存在非法字符
	 */
	public static boolean checkSQLInject(String str, String url) {
		if (StringUtils.isEmpty(str)) {
			return false;// 如果传入空串则认为不存在非法字符
		}

		// 判断黑名单
		String[] inj_stra = { "script", "mid", "master", "truncate", "insert", "select", "delete", "update", "declare",
				"iframe", "'", "onreadystatechange", "alert", "atestu", "xss", ";", "'", "\"", "<", ">", "(", ")", ",",
				"\\", "svg", "confirm", "prompt", "onload", "onmouseover", "onfocus", "onerror" };

		str = str.toLowerCase(); // sql不区分大小写

		for (int i = 0; i < inj_stra.length; i++) {
			if (str.indexOf(inj_stra[i]) >= 0) {
				logger.info("xss防攻击拦截url:" + url + ",原因:特殊字符,传入str=" + str + ",包含特殊字符:" + inj_stra[i]);
				return true;
			}
		}
		return false;
	}
}
  • 10
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要实现对当前服务所有带有 `@RequestBody` 注解POST 请求请求对象参数的某个同名参数进行统一校验,你可以使用 Spring 框架提供的校验功能结合 AOP(面向切面编程)的方式实现。 首先,创建一个自定义的注解,例如 `@CustomValidation`,用于标记需要进行统一校验的参数。在需要进行校验的参数上添加该注解: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface CustomValidation { } ``` 接下来,创建一个切面类,用于拦截带有 `@RequestBody` 注解POST 请求,并进行统一校验。在切面类,使用 `@Before` 注解标记一个方法,在该方法实现校验逻辑: ```java @Aspect @Component public class RequestBodyValidationAspect { @Autowired private Validator validator; @Before("@annotation(org.springframework.web.bind.annotation.PostMapping) && args(.., @RequestBody requestBody)") public void validateRequestBody(JoinPoint joinPoint, Object requestBody) throws Throwable { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = methodSignature.getMethod(); Parameter[] parameters = method.getParameters(); for (int i = 0; i < parameters.length; i++) { if (parameters[i].isAnnotationPresent(CustomValidation.class)) { Object value = getValueOfParameter(requestBody, parameters[i].getName()); Set<ConstraintViolation<Object>> violations = validator.validate(value); if (!violations.isEmpty()) { throw new IllegalArgumentException(violations.iterator().next().getMessage()); } } } } private Object getValueOfParameter(Object requestBody, String parameterName) throws NoSuchFieldException, IllegalAccessException { Field field = requestBody.getClass().getDeclaredField(parameterName); field.setAccessible(true); return field.get(requestBody); } } ``` 在上述代码,切面类 `RequestBodyValidationAspect` 使用了 `@Aspect` 和 `@Component` 注解,表示它是一个切面,并且可以被 Spring 容器扫描到。 在 `validateRequestBody` 方法,通过 `@Before` 注解指定了切入点,即拦截所有带有 `@PostMapping` 注解的方法,并且方法参数带有 `@RequestBody` 注解参数。然后,根据方法参数注解 `@CustomValidation`,获取对应的参数值,并使用 `Validator` 对其进行校验。 最后,可以在你的请求对象参数,为需要进行校验的参数添加 `@CustomValidation` 注解,例如: ```java public class MyRequest { @CustomValidation private String param; // getter and setter } ``` 这样,在所有带有 `@RequestBody` 注解POST 请求,只有带有 `@CustomValidation` 注解参数会进行统一校验。如果校验失败,将抛出异常并返回相应的错误信息。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值