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