基于spring自动注入及AOP的表单二次提交验证

£可爱£侵袭症+ 提交于 2020-03-10 23:24:50

这几天在网上闲逛,看到了几个关于spring的token二次提交问题,受到不少启发,于是自己动手根据自己公司的项目框架结构,制作了一个基于spring自动注入加上AOP的表单二次提交。

原理:建立两个注解类,一个进行token的设置,一个进行token的验证。在一个Aspect中,对这两个注解进行捕获并进行相应的验证。

废话不多说,下面是代码:

Token注解类,标记需要设置token的方法。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) //设定此注解对应的是方法。
public @interface Token { }
TokenValid注解类,标记需要验证token的方法。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TokenValid { }

TokenAspect类,对上面两个注解标识的方法的访问进行捕获并处理。 

 

@Aspect
@Component
public class TokenAspect {
	@Around("@annotation(token)") //可以直接捕获下面这个方法中参数所设定的注解类型
	public void addToken(ProceedingJoinPoint joinPoint, Token token) throws Throwable{
		Object[] args = joinPoint.getArgs();
		String className = joinPoint.getTarget().getClass().getName();
		for(Object a : args){
			if(a != null && a instanceof HttpServletRequest){
				HttpServletRequest request = (HttpServletRequest)a;
				HttpSession session = request.getSession(true);
				String flag = MD5Eencryption.md5_32(className + new Date().getTime()); //创建一个token的flag
				session.setAttribute("TokenFlag" + className, flag);
				request.setAttribute("token", flag);
				joinPoint.proceed();
			}
		}
		
	}
	
	@Around("@annotation(tokenValid)")
	public void checkToken(ProceedingJoinPoint joinPoint, TokenValid tokenValid) throws Throwable{
		Object[] args = joinPoint.getArgs();
		String className = joinPoint.getTarget().getClass().getName();
		for(Object a : args){
			if(a != null && a instanceof HttpServletRequest){
				HttpServletRequest request = (HttpServletRequest)a;
				System.out.println(request.getRequestedSessionId());
				HttpSession session = request.getSession(true);
				Object sessionFlag = session.getAttribute("TokenFlag" + className);
				Object requestFlag = request.getParameter("token");
				if(sessionFlag != null &&sessionFlag.equals(requestFlag)){ //验证结果一致,既为第一次提交,删除会话中存储的token,并继续执行方法。否则不做任何处理。
					session.removeAttribute("TokenFlag" + className);
					joinPoint.proceed();
				}
			}
		}
	}
}

使用:
需要工程开启spring的自动注入及AOP功能。
在需要设定token的方法前面增加注解:@Token,需要验证token的方法前面增加注解:@TokenValid。例如:

@TokenValid //会对访问此方法的请求验证token是否正确。
@RequestMapping(params = "method=save")
public String save(String type, HttpServletRequest request){
	//...业务处理
}

前台页面的表单中,增加下面内容来提交token以便TokenValid的验证。

<input type="hidden" name="token" value="${requestScope.token}" />
如果表单为二次提交,将不会执行 @TokenValid标记的方法。

目前的问题:
1.局限了两个调用方法必须有一个参数为HttpServletRequest的对象。否则无法对请求和会话进行处理。
2.如果二次提交,没有返回提醒,直接返回的结果为空白页面。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!