重大改版
 鱼翔空 2013-06-19 技术总结|   0 941 
文章评分 90 次,平均分 5.0

二十八:权限设计

 在用户登录的时候需要读取出用户的权限,并将用户的权限位和权限码放入到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 ;
            }
        }
    }


 

除特别注明外,本站所有文章均为我要编程原创,转载请注明出处来自http://5ycode.com/article/227.html

关于
该用户很懒!
切换注册

登录

忘记密码 ?

切换登录

注册

扫一扫二维码分享