前言
spring中的另一个大头aop,其强大无法言喻,之前一直基于理论知识,没有做具体的实现,在项目上遇到了需要对接口做权限控制的时候,故想到了aop,如下是实现过程。
背景
当前项目上是在菜单管理那块做了对应的权限字符串的控制,控制当前页面是有哪些类型的操作
在配置角色的权限的时候,可以去控制当前角色可以进行哪些操作
总而言之,我们只需要在接口上配置对应的权限字符串,查询到该用户所对应的角色有对应的字符串权限,那就可以继续请求目标接口,否则就打回响应为403.
实现
1. 注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RootManager {
// 操作权限字符串
String type() default "";
}
2. 标明切点是所有运用上该注解的方法
**
* 切点,需要拦截的是所有加上该注解的方法
*/
@Pointcut("@annotation(cn.sunline.mrms.commons.AOP.RootManager)")
public void AroundPointCut(){
}
3. 权限判断方法
因为我们需要去控制目标方法的执行与否,所有必须使用环绕方法,通过point.proceed()去执行目标方法
/**
* 方法执行前做判断
* @param point
* @return
*/
@Around("AroundPointCut()")
public Object exceptionHandler (ProceedingJoinPoint point) throws Throwable {
String userName = cookieService.getCurrentUser().getUserName();
SQLQuery query = HibernateUtil.currentSession().createSQLQuery("SELECT pu.IS_ADMIN FROM PF_USER pu WHERE pu.USER_NAME = :userName");
query.setParameter("userName",userName);
String isAdmin = query.uniqueResult().toString();
// 超级管理员可直接请求
if ("1".equals(isAdmin)) {
return point.proceed();
}
// 获取参数中的菜单数据,结合sql查询是否有对应的类型
String params = RequestParamsHandle.FParams();
// 注解获取参数
MethodSignature signature = (MethodSignature) point.getSignature();
RootManager rootManager = signature.getMethod().getAnnotation(RootManager.class);
String type = rootManager.type();
Map<String, Object> map = (Map<String, Object>) JSONObject.parse(params.replace("[","").replace("]",""));
String opMenu = map.get("opMenu").toString();
String menuName = opMenu.substring(opMenu.indexOf('/') + 1,opMenu.length() );
SQLQuery sqlQuery = HibernateUtil.currentSession().createSQLQuery("SELECT\n" +
"\t*\n" +
"FROM\n" +
"\tPF_RES_ATTR_DATA a\n" +
"LEFT JOIN PF_MENU_FUNCTION b ON\n" +
"\ta.RES_REC_ID = b.F_ID\n" +
"WHERE\n" +
"\ta.ATTR_REC_ID = (\n" +
"\tSELECT\n" +
"\t\tROLE_ID\n" +
"\tFROM\n" +
"\t\tPF_USER pu\n" +
"\tWHERE\n" +
"\t\tpu.USER_NAME = :userName) AND b.F_MENUID = (SELECT pm.ID FROM PF_MENU pm WHERE pm.NAME = :menuName) AND b.F_FUNCTIONID = :type");
sqlQuery.setParameter("menuName",menuName);
sqlQuery.setParameter("userName",userName);
sqlQuery.setParameter("type",type);
List list = sqlQuery.list();
if (list.size() > 0) {
return point.proceed();
}
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return Message.error("403","无权限");
}
4. 汇总
/**
* 权限控制切面
* @Author zmx
* @Date 2022/11/28 15:47
*/
@Aspect
@Component
public class RootManagerAdvice {
@Autowired
private CookieService cookieService;
@Autowired
private HttpServletResponse response;
/**
* 切点,在注解处切入
*/
@Pointcut("@annotation(cn.sunline.mrms.commons.AOP.RootManager)")
public void AroundPointCut(){
}
/**
* 方法执行前做判断
* @param point
* @return
*/
@Around("AroundPointCut()")
public Object exceptionHandler (ProceedingJoinPoint point) throws Throwable {
String userName = cookieService.getCurrentUser().getUserName();
SQLQuery query = HibernateUtil.currentSession().createSQLQuery("SELECT pu.IS_ADMIN FROM PF_USER pu WHERE pu.USER_NAME = :userName");
query.setParameter("userName",userName);
String isAdmin = query.uniqueResult().toString();
// 超级管理员可直接请求
if ("1".equals(isAdmin)) {
return point.proceed();
}
// 获取参数中的菜单数据,结合sql查询是否有对应的类型
String params = RequestParamsHandle.FParams();
// todo 注解获取参数
MethodSignature signature = (MethodSignature) point.getSignature();
RootManager rootManager = signature.getMethod().getAnnotation(RootManager.class);
String type = rootManager.type();
Map<String, Object> map = (Map<String, Object>) JSONObject.parse(params.replace("[","").replace("]",""));
String opMenu = map.get("opMenu").toString();
String menuName = opMenu.substring(opMenu.indexOf('/') + 1,opMenu.length() );
SQLQuery sqlQuery = HibernateUtil.currentSession().createSQLQuery("SELECT\n" +
"\t*\n" +
"FROM\n" +
"\tPF_RES_ATTR_DATA a\n" +
"LEFT JOIN PF_MENU_FUNCTION b ON\n" +
"\ta.RES_REC_ID = b.F_ID\n" +
"WHERE\n" +
"\ta.ATTR_REC_ID = (\n" +
"\tSELECT\n" +
"\t\tROLE_ID\n" +
"\tFROM\n" +
"\t\tPF_USER pu\n" +
"\tWHERE\n" +
"\t\tpu.USER_NAME = :userName) AND b.F_MENUID = (SELECT pm.ID FROM PF_MENU pm WHERE pm.NAME = :menuName) AND b.F_FUNCTIONID = :type");
sqlQuery.setParameter("menuName",menuName);
sqlQuery.setParameter("userName",userName);
sqlQuery.setParameter("type",type);
List list = sqlQuery.list();
if (list.size() > 0) {
return point.proceed();
}
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
return Message.error("403","无权限");
}
}