有时候,我们有的链接需要控制权限,判断用户是否有权限,若是没有权限则提示用户无权限访问,如果每个请求方法都自己写一套,那么实在是太麻烦了,还会漏,但是这里也不应该放在拦截器中,因为拦截器中判断了是否登录,只有登录了才会有权限判断这一步。
这里,自定义一个权限注解,开发人员若是觉得某一个请求需要判断权限,那么加上该注解即可,若是不需要判断权限,则不需要加上该注解。
实现逻辑如下(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;
}
}