有时候,我们有的链接需要控制权限,判断用户是否有权限,若是没有权限则提示用户无权限访问,如果每个请求方法都自己写一套,那么实在是太麻烦了,还会漏,但是这里也不应该放在拦截器中,因为拦截器中判断了是否登录,只有登录了才会有权限判断这一步。
这里,自定义一个权限注解,开发人员若是觉得某一个请求需要判断权限,那么加上该注解即可,若是不需要判断权限,则不需要加上该注解。
实现逻辑如下(AOP方式)
一、自定义一个权限注解
/*** 若是方法上加了这个注解,就表明该方法是需要判断权限的,只能用在Controller上面 @AuthCheck* @author lwh*/@Target({ElementType.METHOD})//只能用在方法上面@Retention(RetentionPolicy.RUNTIME)public @interface AuthCheck {}
二、写一个AOP,通过反射的方式来判断请求的方法是否有权限注解
/** 使用AOP统一处理权限* @author forever*/@Aspect@Component@Order(1)//AOP执行的顺序,数字越小越先执行public class AuthCheckAspect {private static final Logger logger = LoggerFactory.getLogger(AuthCheckAspect.class);private String result2= "{\"user_auth\":\"no\"}";@Pointcut("execution(public * com.xxx.xxx.xxx.web.*.*(..))")public void webLog() {}@Around("webLog()")public Object doAround(ProceedingJoinPoint pjp) throws Throwable {Method realMethod = getControllerMethod(pjp);AuthCheck authCheck = realMethod.getDeclaredAnnotation(AuthCheck.class);if(authCheck!=null) {ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();String httpUrl = httpUrl(request);logger.info("权限AOP判断到方法上有注解webLog");//判断用户是否有权限.有则继续执行,没有就抛出异常,表明没有权限访问Boolean result = checkUserAuth(httpUrl,request.getSession());if(!result) {logger.error("用户没有权限访问");//XMLHttpRequest这个表示异步String requestType = request.getHeader("X-Requested-With");//HttpServletResponse response = attributes.getResponse();if(requestType!=null) {//这里直接返回,因为这个就相当于是controller返回return result2;}else {//这里相当于重定向到auth请求return "auth";}}}return pjp.proceed();}private Boolean checkUserAuth(String httpUrl, HttpSession session) {logger.info("判断请求:http_method:"+httpUrl);//这里用户肯定 是已经登录,的,不然会在上一步拦截,将会到不了这里User user =(User) session.getAttribute(Const.USER_KEY);if(user!=null) {//String id = user.getUser_id();//封装权限KEY//logger.info("用户菜单权限对应的key是:"+key);//从session中获取,菜单链接对应的权限,map中是权限链接对应的权限名称@SuppressWarnings("unchecked")Map<String,String> map = (Map<String, String>) session.getAttribute(Const.AUTH_KEY);if(map!=null&&map.size()>0) {//根据请求菜单,查看是否有权限String auth_sys_name = map.get(httpUrl);if(StringUtils.isNotBlank(auth_sys_name)) {logger.info("用户有访问:"+auth_sys_name+"的权限");return true;}}}logger.info("用户没有访问:"+httpUrl+"的权限");return false;}private String httpUrl(HttpServletRequest request) {String requestURI = request.getRequestURI();return requestURI;}private Method getControllerMethod(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {Signature signature = pjp.getSignature();MethodSignature methodSignature = (MethodSignature)signature;Method targetMethod = methodSignature.getMethod();String name = signature.getName();logger.info("进入权限AOP的方法名称:"+name);Method realMethod = pjp.getTarget().getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());return realMethod;}}
