二十八:权限设计
在用户登录的时候需要读取出用户的权限,并将用户的权限位和权限码放入到session中,
使用spring的applicationListener监听器,在服务器启动的时候就将所有的权限放入到application中
/** * 事件监听器 */ @SuppressWarnings("rawtypes") @Component public class IniRightListener implements ApplicationListener,ServletContextAware{ @Resource private RightService rs ; //接收servletContext private ServletContext sc; public void onApplicationEvent(ApplicationEvent arg0) { if(arg0 instanceof ContextRefreshedEvent){ List<Right> list = rs.findAllEntities(); Map<String,Right> map = new HashMap<String, Right>(); for(Right r : list){ map.put(r.getRightUrl(), r); } if(sc != null){ //将所有权限存放到application中 sc.setAttribute("all_rights_map", map); } System.out.println("初始化权限完成"); } } //注入servletContext public void setServletContext(ServletContext servletContext) { this.sc = servletContext ; } }
优点:
* 只需要登录的时候,将用户的权限位和该权限为对应的权限码的|运算出来的数据保存到session
long rightSum[] 数组的索引对应的是权限位,数组的值,对应的是权限码
/** * 计算权限总和 */ public void calculateRightSum() { int pos = 0 ; long code = 1 ; for(Role role : roles){ if("-1".equals(role.getRoleValue())){ this.superAdmin = true ; //将user对象图上的其他对象清空,减小session中数据的存储量 roles = null ; return ; } for(Right r : role.getRights()){ pos = r.getRightPos(); code = r.getRightCode(); rightSum[pos] = rightSum[pos] | code ; } } //将user对象图上的其他对象清空,减小session中数据的存储量 roles = null ; }
* session中不需要保存所有的数据,只需要保存这些数字就可以了,减轻服务器的压力和session数据的存放量
* 不需要每次访问都需要去找用户的角色(roles)和权限(rights),访问速度和验证速度都会加快
* 只需要拿当前访问的/namespace/actionName去数据库中查找对应的权限位和权限码,拿这些权限位和权限码去
/** * 是否具有指定权限,根据url获取right对象 */ public boolean hasRight(Right r) { int pos = r.getRightPos(); long code = r.getRightCode(); long ret = rightSum[pos] & code ; return ret == 0 ?false:true; }
改造登录拦截器为权限拦截器
public String intercept(ActionInvocation arg0) throws Exception { BaseAction action = (BaseAction) arg0.getAction(); ActionProxy proxy = arg0.getProxy(); String ns = proxy.getNamespace(); String actionName = proxy.getActionName(); if(ValidateUtil.hasRight(actionName, ns, ServletActionContext.getRequest(), action)){ return arg0.invoke(); } else{ return "login" ; } }
/** * 判断是否有权限 */ public static boolean hasRight(String actionName,String ns,HttpServletRequest req,BaseAction action){ String url = "" ; if(!ValidateUtil.isValid(ns) || ns.equals("/")){ ns = "" ; } url = ns + "/" + actionName ; //得到ServletContext + Session ServletContext sc = req.getSession().getServletContext(); HttpSession session = req.getSession(); //得到权限,将所有的url和对应的权限放入了application中去了,不需要再查数据库 Map<String, Right> map = (Map<String, Right>) sc.getAttribute("all_rights_map"); //判断是否登陆 User u = (User) session.getAttribute("user"); //判断当前访问的action是否实现了UserAware对象(实现了说明该action需要注入user对象) if(u != null && action != null && action instanceof UserAware){ ((UserAware)action).setUser(u); } Right r = map.get(url); if(r == null || r.isCommon()){ return true ; } //不是 else{ //登陆? if(u != null){ //超级管理员? if(u.isSuperAdmin()){ return true; } //不是 else{ if(u.hasRight(r)){ return true ; } else{ return false ; } } } else{ return false ; } } }
文章评论