springbooot通过aop的before做权限验证

原创
04/30 11:50
阅读数 25

1、权限注解:

import java.lang.annotation.*;

@Target({ElementType.PARAMETER, ElementType.METHOD})  

@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface PermAnno {
 
     /** 方法所属用户类型比如: "1","2","1,2" 
      *  也可以是角色名称组合如:"超级管理","运维人员","超级管理员,运维人员"
     **/  
    public String menuType() default "";  
      
}

2、方法上添加注解:

@PermAnno(menuType="1,2,3,4,5")
	@RequestMapping(value = "/logout", method = RequestMethod.POST)
	Map<String, Object> logout( HttpServletRequest req, HttpServletResponse response) {
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			return result;
		} catch (Exception e) {
			result.put("successful", "false");
			result.put("msg", "退出失败");
			return result;
		}
	}

3、AOP拦截:


@Aspect
@Component
@Order(3)
public class CommonAop {

	 
	//申明一个切点 里面是 execution表达式
	   @Pointcut("execution(* com.sgcc.vul.controller.*.*(..))")
	   private void controllerAspect(){}
	 
	  //请求method前打印内容
	   @SuppressWarnings({"unchecked" })
	   @Before(value = "controllerAspect()")
	   public void methodBefore(JoinPoint joinPoint) throws Exception{
	       ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
	       HttpServletRequest request = requestAttributes.getRequest();
	        Map<String,Object> userObj = (Map<String,Object>)request.getSession().getAttribute("userObj");
	        if(userObj == null || userObj.get("userType") == null){
	        	throw new Exception("没有用户");
	        }
	        //用户类型
	        int userType = Integer.parseInt(userObj.get("userType")+"");
	        String annoValue = "";
			try {
			    Method methdo = ((MethodSignature) joinPoint.getSignature()).getMethod();
			    if (methdo.getAnnotation(PermAnno.class) != null) {
			        PermAnno anno = methdo.getAnnotation(PermAnno.class);
			        annoValue = anno.menuType();
			        /***
			         * 在角色名称可以预知的情况下
			         * menuType可以直接使用角色名称;
			         * 当前用户如果有多个角色,则userType替换为角色名称以逗号拼接
			         * 在for循环内部,再遍历一次角色名称
			         */
			        String[] annoArr = annoValue.split(",");
			        boolean flag = false;
			        for(String annoV : annoArr){
			        	if(userType == Integer.parseInt(annoV)){
			        		flag = true;
			        		break;
			        	}
			        }
			        if(!flag){
			        	throw new Exception("没有访问该接口权限");
			        }
			    } else {
			    	throw new Exception("没有访问该接口权限");
			    }
			} catch (Exception ex) {
				ex.printStackTrace();
			    throw new Exception("没有访问该接口权限");
			}
	   }
	
	   //在方法执行完结后记录用户操作痕迹内容
	   @SuppressWarnings("unchecked")
	   @AfterReturning(returning = "o",pointcut = "controllerAspect()")
	   public void methodAfterReturing(Object o ){
		   try {
			 //保存用户操作痕迹
		   }catch(Exception e) {
			   e.printStackTrace();
		   }
	   }
	
}

@Before拦截,是在执行方法前进行拦截,参数用的是JoinPoint类型对象,如果有执行方法的权限,则没有任何返回值,否则抛出异常;

如果参数类型ProceedingJoinPoint类型对象,则需要用@Around,就是环绕,在方法执行前和执行后,分别运行一次。如果有执行方法的权限,则执行joinPoint.proceed()方法通过权限认证。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部