项目中需要用到权限控制,简单的方案记录下。
自定义一个注解@CheckPermission。
/**
* 检查权限
* @author yanyimin
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckPermission {
}
aop中实现的方法:
@Configuration
@Aspect
public class PermissionProxy extends BaseLogger{
@Autowired
AdminService adminService;
@Autowired
PermissionCache permissionCache;
@Around("@annotation(com.runrong.managecenter.business.aop.CheckPermission)")
public Object check(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
//获取被代理方法的类名
String className=signature.getDeclaringTypeName();
//获取被代理的方法名
Method method = signature.getMethod();
String methodName=method.getName();
//通过方法参数获取到session,拿到用户信息
for (Object arg : point.getArgs()) {
if (!(arg instanceof HttpServletRequest)) {
continue;
}
HttpServletRequest request = (HttpServletRequest) arg;
HttpSession session =request.getSession();
//拿到储存在session中的用户id
int id=(int) session.getAttribute("admin_id");
//拿到储存在session中的用户类型
int type=(int) session.getAttribute("admin_type");
//0:超级管理员,1:管理员
//当用户为超级管理员时,拥有所有权限,可以通过权限检查的方法。
if(type==0){
return point.proceed();
}
//每次都需要查询数据库 权限验证较为频繁可以引入缓存
List<String> permission;
if(permissionCache.get(String.valueOf(id)) == null){
//根据用户id获取用户权限
permission=adminService.getAdminPermission(id);
//写入缓存中
permissionCache.put(String.valueOf(id),permission);
}else{
//logger.info("用户:"+id+",从缓存中验证权限:"+className+"_"+methodName);
permission=permissionCache.get(String.valueOf(id));
}
//如果用户权限中包含aop代理下的方法,则该用户权限验证通过
if(permission.contains(className+"_"+methodName)){
return point.proceed();
}
//按钮采用post方法,通过ajax调用返回json串,提示无权限
if(methodName.endsWith("POST")){
return ResultModel.successModel("无权限使用此功能");
}
//进入页面采用get方法,若无权限则进行页面跳转
return new ModelAndView("redirect:/managecenter/nopermission.html");
}
throw new RuntimeException("the method which use @CheckPermission must has a HttpServletRequest as Parameter");
}
}
在controller中需要实现权限控制的方法上加上此注解:
/**
* 管理员账号控制层
* @author yanyimin
*
*/
@Controller
@RequestMapping("/managecenter")
public class AdminController {
@Autowired
AdminService adminService;
/**
* 添加管理员
* @param request
* @return
*/
@RequestMapping(value="/addAdministrator" ,method=RequestMethod.GET)
@CheckPermission
public ModelAndView addAdministratorGET(HttpServletRequest request) {
return new ModelAndView("/managecenter/addAdministrator");
}
/**
* 添加管理员
* @param request
* @return
*/
@RequestMapping(value="/addAdministrator" ,method=RequestMethod.POST)
@ResponseBody
@CheckPermission
public ResultModel addAdministratorPOST(HttpServletRequest request){
return adminService.addAdministrator(request);
}
}
这样在使用添加管理员这个功能时,会先进入到aop中进行权限的检查。
权限使用类名+方法名的方式储存在数据库中,用get、post方法分别作为页面和按钮的权限控制。