javaWeb用户权限控制简单实现

最近在做一个网站类型的项目,要对用户的访问模块(权限)进行控制,所以设计并实现了一套简单的权限控制功能。

1. 数据库设计

用户:users

模块:modules

 

SQL代码:

 

/*
Target Server Type    : MYSQL
Target Server Version : 50628
File Encoding         : 65001

Date: 2016-08-26 10:35:28
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `modules`
-- ----------------------------
DROP TABLE IF EXISTS `modules`;
CREATE TABLE `modules` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `module` varchar(30) DEFAULT NULL COMMENT '模块',
  `pid` int(10) DEFAULT NULL COMMENT '上一级id',
  `level` int(4) DEFAULT NULL COMMENT '级别',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of modules
-- ----------------------------

-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `user_code` varchar(10) NOT NULL COMMENT '用户代码',
  `user_name` varchar(40) DEFAULT NULL COMMENT '用户名',
  `user_password` varchar(100) DEFAULT NULL COMMENT '密码',
  `qq` varchar(15) DEFAULT NULL COMMENT 'qq',
  `msn` varchar(50) DEFAULT NULL COMMENT 'msn',
  `demo` varchar(100) DEFAULT NULL COMMENT '备注',
  `auth_code` text COMMENT '权限码',
  PRIMARY KEY (`user_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of users
-- ----------------------------

1. 后端实现

项目中用SSM+freemarker框架,把权限封装成权限树的数据结构,然后转成json格式。

1) 展示层采用ztree树(setUserauthOnTree.html)




<#include "common/res.html" />










	

    展示效果如下:

     

    2) controller控制层用springmvc

     

    在控制层把数据转成json格式,发到展示层。

    /**
    	 * @fun 获取分店用户权限
    	 * @author 皮锋
    	 * @date 2016/8/25
    	 * @param session
    	 * @param id
    	 * @param substoreid
    	 * @return
    	 */
    	@RequestMapping("getUserRightMaskById")
    	@ResponseBody
    	public Object getUserRightMaskById(HttpSession session,String id,String substoreid){
    		substoreid=StringUtils.isEmpty(substoreid)?String.valueOf(session.getAttribute("substoreid")):substoreid;
    		//判断是酒店还是客栈
    		List> versionsList=this.setupService.getHotelHotelVersions(substoreid);
    		Object versions=versionsList.get(0).get("versions");
    		Map hotelMap=new HashMap();
    		if((null!=versionsList)&&(versionsList.size()!=0)){  //list不为空
    			if("complete".equals(versions)){   //酒店
    				//查询酒店权限树
    				hotelMap=this.rightMaskService.getUserRightMaskOnTree(substoreid,id,"complete");
    			}else if("simple".equals(versions)){  //客栈
    				//查询客栈权限树
    				hotelMap=this.rightMaskService.getUserRightMaskOnTree(substoreid,id,"simple");
    			}
    		}
    		Map resultMap = new HashMap();
    		resultMap.put("datas", hotelMap);
    		
    		return JSONObject.toJSONString(resultMap, SerializerFeature.WriteMapNullValue);
    	}

    3)service服务层把权限封装成满足ztree格式的树数据结构

    /**
    	 * @fun 获取分店用户权限
    	 * @author 皮锋
    	 * @date 2016/8/25
    	 * @param substoreid
    	 * @param id
    	 * @param versions
    	 * @return Map
    	 */
    	@Override
    	public Map getUserRightMaskOnTree(String substoreid, String id, String versions) {
    		Map userRightMask=this.iRightMaskDao.getUserRightMaskBySubAndId(substoreid,id);
    		List> listOne = new ArrayList>();
    		List> listTwo = new ArrayList>();
    		//List> listThree = new ArrayList>();
    		List> resultList = new ArrayList>();
    		if(versions.equals("complete")){  //酒店
    			listOne = this.iRightMaskDao.getRightMaskOnHotelOne();
    			listTwo = this.iRightMaskDao.getRightMaskOnHotelTwo();
    			//listThree = this.iRightMaskDao.getRightMaskOnHotelThree();
    			packagingToTwoTree(resultList,listOne,listTwo,userRightMask);
    		}else if(versions.equals("simple")){  //客栈
    			listOne = this.iRightMaskDao.getRightMaskOnTavernOne();
    			listTwo = this.iRightMaskDao.getRightMaskOnTavernTwo();
    			//listThree = this.iRightMaskDao.getRightMaskOnTavernThree();
    			packagingToTwoTree(resultList,listOne,listTwo,userRightMask);
    		}
    		Map map = new HashMap();
    		map.put("data", resultList);
    		return map;
    	}
    /**
    	 * @function 封装一个一级树
    	 * @author 皮锋
    	 * @date 2016/8/26
    	 * @param resultList
    	 * @param listOne
    	 * @param authCode
    	 * @return void
    	 */
    	private void packagingToOneTree(List> resultList,
    			List> listOne, Map authCode) {
    		for (int i = 0; i < listOne.size(); i++) {
    			Map rootMap = new HashMap();
    			rootMap.put("id", listOne.get(i).get("id"));
    			rootMap.put("name", listOne.get(i).get("module"));
    			if (validateRightMask(listOne, authCode, i) != -1) {
    				rootMap.put("checked", true);
    			} else {
    				rootMap.put("checked", false);
    			}
    			resultList.add(rootMap);
    		}
    	}
    
    	/**
    	 * @function 封装一个二级树
    	 * @author 皮锋
    	 * @date 2016/8/26
    	 * @param resultList
    	 * @param listOne
    	 * @param listTwo
    	 * @param authCode
    	 * @return void
    	 */
    	private void packagingToTwoTree(List> resultList,
    			List> listOne,
    			List> listTwo, Map authCode) {
    		for (int i = 0; i < listOne.size(); i++) {
    
    			List> midList = new ArrayList>();
    			for (int j = 0; j < listTwo.size(); j++) {
    
    				if (listTwo.get(j).get("pid").toString()
    						.equals(listOne.get(i).get("id").toString())) {
    
    					List> minlist = new ArrayList>();
    
    					Map midMap = new HashMap();
    					midMap.put("id", listTwo.get(j).get("id"));
    					midMap.put("name", listTwo.get(j).get("module"));
    					midMap.put("children", minlist);
    					if (validateRightMask(listTwo, authCode, j) != -1) {
    						midMap.put("checked", true);
    					} else {
    						midMap.put("checked", false);
    					}
    					midList.add(midMap);
    				}
    			}
    			Map rootMap = new HashMap();
    			rootMap.put("id", listOne.get(i).get("id"));
    			rootMap.put("name", listOne.get(i).get("module"));
    			rootMap.put("children", midList);
    			if (validateRightMask(listOne, authCode, i) != -1) {
    				rootMap.put("checked", true);
    			} else {
    				rootMap.put("checked", false);
    			}
    			resultList.add(rootMap);
    		}
    	}
    
    	/**
    	 * @function 封装一个三级树
    	 * @author 皮锋
    	 * @date 2016/8/26
    	 * @param resultList
    	 * @param listOne
    	 * @param listTwo
    	 * @param listThree
    	 * @param authCode
    	 * @return void
    	 */
    	private void packagingToThreeTree(List> resultList,
    			List> listOne,
    			List> listTwo,
    			List> listThree, Map authCode) {
    		for (int i = 0; i < listOne.size(); i++) {
    
    			List> midList = new ArrayList>();
    			for (int j = 0; j < listTwo.size(); j++) {
    
    				if (listTwo.get(j).get("pid").toString()
    						.equals(listOne.get(i).get("id").toString())) {
    
    					List> minlist = new ArrayList>();
    
    					for (int k = 0; k < listThree.size(); k++) {
    						Map minMap = new HashMap();
    						if (listThree.get(k).get("pid").toString()
    								.equals(listTwo.get(j).get("id").toString())) {
    							minMap.put("id", listThree.get(k).get("id"));
    							minMap.put("name", listThree.get(k).get("module"));
    							if (validateRightMask(listThree, authCode, k) != -1) {
    								minMap.put("checked", true);
    							} else {
    								minMap.put("checked", false);
    							}
    							minlist.add(minMap);
    						}
    					}
    					Map midMap = new HashMap();
    					midMap.put("id", listTwo.get(j).get("id"));
    					midMap.put("name", listTwo.get(j).get("module"));
    					midMap.put("children", minlist);
    					if (validateRightMask(listTwo, authCode, j) != -1) {
    						midMap.put("checked", true);
    					} else {
    						midMap.put("checked", false);
    					}
    					midList.add(midMap);
    				}
    			}
    			Map rootMap = new HashMap();
    			rootMap.put("id", listOne.get(i).get("id"));
    			rootMap.put("name", listOne.get(i).get("module"));
    			rootMap.put("children", midList);
    			if (validateRightMask(listOne, authCode, i) != -1) {
    				rootMap.put("checked", true);
    			} else {
    				rootMap.put("checked", false);
    			}
    			resultList.add(rootMap);
    		}
    	}
    
    	/**
    	 * @function 验证authCode中是否有list中的权限码
    	 * @author 皮锋
    	 * @date 2016/8/26
    	 * @param list
    	 * @param authCode
    	 * @param i
    	 * @return int
    	 */
    	private int validateRightMask(List> list,
    			Map authCode, int i) {
    		String rightMask = authCode.get("auth_code") != null ? authCode.get(
    				"auth_code").toString() : "";
    		if (!StringUtils.isEmpty(rightMask)) {
    			rightMask = rightMask.replace(";", ",");
    			String[] arry = rightMask.split(",");
    			for (int j = 0; j < arry.length; j++) {
    				String arryRightMask = arry[j];
    				String listRightMask = list.get(i).get("id").toString();
    				if (arryRightMask.equals(listRightMask)) {
    					return 1;
    				}
    			}
    		} else {
    			return -1;
    		}
    		return -1;
    	}

    4) dao层查询数据库获得用户权限

    a.在数据层按权限级别从modules表中分别拿出不同级别的权限

    select id,module,pid,level from modules where level='0'

    select id,module,pid,level from modules where level='1'

    select id,module,pid,level from modules where level='2'

    b.在users表中拿出某用户的所有权限(权限码)

    select auth_code from users where user_code='pifeng'

    c.保存权限时不同级别之间的权限码用英式分号“;”隔开,同一级别之间的权限码用英式逗号“,”隔开。例如:1,2,3,4,5,6,7,8,9,10,11,12;13,14,15,16,17,18,19,20,21,22,23,24,25,26,36,37,27,28,29,30,31,32,33,34,35,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,56,57,58,59,60,61,62,63,64,133,65,66,67,68,69,70,71,72,73,74,75,126,127,128,129,130,131,76,77,78,79,80,81,82,83,84,85,86,87,88,99,124,134,135,136,140,141,89,90,91,92,93,94,95,96,97,98,137,138,139,100,101,102,103,106,107,132,108,109,110,111,112,113,114,115,116,125,117,118,119,120,121,122

    5)根据用户的权限码用freemarker标签控制页面功能模块是否显示

    a.freemarker在xml文件中的配置

    
            
            
                /WEB-INF/ftl/
            
            
                
                    
                
            
            
                
                    auto_detect
                    0
                    UTF-8
                    UTF-8
                    zh_CN
                    yyyy-MM-dd
                    HH:mm:ss
                    0.######
                    yyyy-MM-dd HH:mm:ss
                    
                    true
                    
                    inc/spring.ftl as base
                
            
        
    
        
    
        
            
            
            
            
            
            
            
            
            
            
            
            
              
    	          
    	              
    	              
    	                  
    	                  
    	              
    	          
    	      
        

    b.写个类继承TemplateMethodModel类,实现freemarker自定义方法,用于实现控制页面模块是否显示

    登陆的时候把用户权限码存入session中,然后从session中取权限。下面是一个例子:

    public class MenuFunction implements TemplateMethodModel{
    	@Override
    	public Object exec(List arg0) throws TemplateModelException { 
    		int level = Integer.valueOf(arg0.get(0).toString()); //模块等级
            int modelId=Integer.valueOf(arg0.get(1).toString()); //模块id
            int count=0; //记录session是否有此模块的权限码
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            HttpSession session=request.getSession();
            Object o = session.getAttribute("info");
            if(o==null)
            	return false;
        	Info info = (Info) o;
        	String authCode=info.getUser().getAuthCode(); //权限码
        	if(authCode.contains(";")){
        		String[] masks=authCode.split(";");
        		String[]  m=masks[level].split(",");
        		for (int i = 0; i < m.length; i++) {
        			if(modelId==Integer.parseInt(m[i])){
        				++count;
        			}else{
        				count+=0;
        			}
    			}
        	}
        	if(count==0){
        		return false;
        	}else{
        		return true;
        	}
        	
    	}
    
    }

    c.在页面使用freemarker标签,控制模块的显示隐藏

    Menucall中的两个参数,第一个为模块等级,第二个为模块的id

    例如:

     

    <#if menucall(1,122)>
    	
  • 预订
  •  

     

     

     

    以上就是对用户的访问模块(权限)进行控制的大体实现。

     

     

     

     

     

     

     

     

     

     

     

     

     

    你可能感兴趣的:(#,基础(非框架))