项目中需要用到权限控制,简单的方案记录下。
自定义一个注解@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方法分别作为页面和按钮的权限控制。
 
  
  
  
 