javaWeb用户权限控制简单实现

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

1. 数据库设计

用户:users

javaWeb用户权限控制简单实现_第1张图片

模块:modules

javaWeb用户权限控制简单实现_第2张图片

SQL代码:

[sql]  view plain  copy
 
  1. /*  
  2. Target Server Type    : MYSQL  
  3. Target Server Version : 50628  
  4. File Encoding         : 65001  
  5.   
  6. Date: 2016-08-26 10:35:28  
  7. */  
  8.   
  9. SET FOREIGN_KEY_CHECKS=0;  
  10.   
  11. -- ----------------------------  
  12. -- Table structure for `modules`  
  13. -- ----------------------------  
  14. DROP TABLE IF EXISTS `modules`;  
  15. CREATE TABLE `modules` (  
  16.   `id` int(10) NOT NULL AUTO_INCREMENT,  
  17.   `module` varchar(30) DEFAULT NULL COMMENT '模块',  
  18.   `pid` int(10) DEFAULT NULL COMMENT '上一级id',  
  19.   `levelint(4) DEFAULT NULL COMMENT '级别',  
  20.   PRIMARY KEY (`id`)  
  21. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  22.   
  23. -- ----------------------------  
  24. -- Records of modules  
  25. -- ----------------------------  
  26.   
  27. -- ----------------------------  
  28. -- Table structure for `users`  
  29. -- ----------------------------  
  30. DROP TABLE IF EXISTS `users`;  
  31. CREATE TABLE `users` (  
  32.   `user_code` varchar(10) NOT NULL COMMENT '用户代码',  
  33.   `user_name` varchar(40) DEFAULT NULL COMMENT '用户名',  
  34.   `user_password` varchar(100) DEFAULT NULL COMMENT '密码',  
  35.   `qq` varchar(15) DEFAULT NULL COMMENT 'qq',  
  36.   `msn` varchar(50) DEFAULT NULL COMMENT 'msn',  
  37.   `demo` varchar(100) DEFAULT NULL COMMENT '备注',  
  38.   `auth_code` text COMMENT '权限码',  
  39.   PRIMARY KEY (`user_code`)  
  40. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  41.   
  42. -- ----------------------------  
  43. -- Records of users  
  44. -- ----------------------------  

1. 后端实现

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

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

[html]  view plain  copy
 
  1. >  
  2. <html>  
  3. <head>  
  4. <#include "common/res.html" />  
  5. <script src="${base.ctx}/js/layer-v2.1/laypage/laypage.js">script>  
  6. <link href="${base.ctx}/js/layer-v2.1/laypage/skin/laypage.css" rel="stylesheet" type="text/css"/>  
  7. <script src="${base.ctx}/js/layer-v2.1/layer/layer.js">script>  
  8.   
  9. <link href="${base.ctx}/component/ztree/css/zTreeStyle/zTreeStyle.css" rel="stylesheet" type="text/css" />  
  10. <script type="text/javascript" src="${base.ctx}/component/ztree/js/jquery.ztree.core-3.5.js">script>  
  11. <script type="text/javascript" src="${base.ctx}/component/ztree/js/jquery.ztree.excheck-3.5.js">script>  
  12. <style type="text/css">  
  13. .blue-madison {  
  14.     border: 1px solid #7ca7cc;  
  15.     border-top: 0;  
  16. }  
  17.   
  18. .caption {  
  19.     background-color: #578ebe;  
  20.     border-bottom: 0;  
  21.     padding: 0 10px;  
  22.     margin-bottom: 0;  
  23.     color: #fff;  
  24. }  
  25. style>  
  26. head>  
  27. <body>  
  28.     <div class="portlet-body"  style="overflow-y:auto; width:400px; height:550px;">  
  29.     <div id="ztree" >  
  30.         <ul id="treeDemo" class="ztree">ul>  
  31.     div>  
  32.     div>  
  33.     <div class="form-actions">  
  34.         <div class="row">  
  35.             <div class="col-sm-12" align="center" style="margin-top: 5px">  
  36.                 <button type='button' class="btn btn-primary"  
  37.                     onclick="editModle()">确定button>  
  38.                 <button type="button" class="btn btn-primary" id="cancel">关闭button>  
  39.             div>  
  40.         div>  
  41.     div>  
  42.     <script>  
  43.         $("document").ready(function() {  
  44.             $.ajax({  
  45.                     type : "post",  
  46.                     url : "${base.ctx}/Setup/getUserRightMaskById",  
  47.                     data:{"id":"${userId}"},  
  48.                     dataType : "json",  
  49.                     success : function(result) {  
  50.                         zTreeObj = $.fn.zTree.init($("#treeDemo"), setting,result.datas.data);  
  51.                         zTreeObj.expandAll(true);  
  52.                     },  
  53.                     error : function() {  
  54.   
  55.                     }  
  56.                 });  
  57.         });  
  58.   
  59.         //加载树  
  60.         var zTreeObj;  
  61.         // zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)  
  62.         var setting = {  
  63.             view : {  
  64.                 //dblClickExpand : false,  
  65.                 showLine : true,                  //是否显示节点间的连线    
  66.             },  
  67.             check: {  
  68.                     enable: true,  
  69.                     //nocheckInherit: false,  
  70.                     chkStyle: "checkbox",  
  71.                     chkboxType: { "Y": "ps", "N": "ps" },  
  72.                     //autoCheckTrigger: true  
  73.             },  
  74.             callback : {  
  75.                 onCheck: zTreeOnCheck,  
  76.             }  
  77.         };  
  78.           
  79.         //checkbox点击的回调事件  
  80.         function zTreeOnCheck(event, treeId, treeNode) {    
  81.             /* var zTree = $.fn.zTree.getZTreeObj("treeDemo");    
  82.             var changedNodes = zTree.getChangeCheckedNodes();    
  83.             for ( var i=0 ; i < changedNodes.length ; i++ ){    
  84.                 var treeNode = changedNodes[i];    
  85.             }   */    
  86.         };    
  87.           
  88.         function editModle(){  
  89.             var rootId=null;  
  90.             var midId=null;  
  91.             var minId=null;  
  92.             var treeObj = $.fn.zTree.getZTreeObj("treeDemo");  
  93.             var nodes = treeObj.getCheckedNodes();  
  94.               
  95.             for(var i=0;i<nodes.length;i++){  
  96.                 if(nodes[i].level==0){  
  97.                     rootId=rootId+","+nodes[i].id;  
  98.                 }  
  99.                 if(nodes[i].level==1){  
  100.                     midId=midId+","+nodes[i].id;  
  101.                 }  
  102.                 if(nodes[i].level==2){  
  103.                     minId=minId+","+nodes[i].id;  
  104.                 }  
  105.             }  
  106.             if(rootId!=null){  
  107.                 rootId=rootId.substring(5,rootId.length);  
  108.             }  
  109.             if(midId!=null){  
  110.                 midId=midId.substring(5,midId.length);  
  111.             }  
  112.             if(minId!=null){  
  113.                 minId=minId.substring(5,minId.length);  
  114.             }  
  115.             $.ajax({  
  116.                     type : "post",  
  117.                     url : "${base.ctx}/Setup/updateUserRightMaskByAjax",  
  118.                     dataType : "json",  
  119.                     data:{"rootId":rootId,"midId":midId,"minId":minId,"userId":"${userId}"},  
  120.                     success : function(result) {  
  121.                         if(result=="1"){  
  122.                             layer.msg("赋权成功!");  
  123.                             setTimeout(function(){top.dialog.get("set-dialog").close().remove();} , 600);  
  124.                         }  
  125.                     },  
  126.                     error : function() {  
  127.                         layer.msg("系统错误,请联系管理员!");  
  128.                     }  
  129.                 });  
  130.         }  
  131.           
  132.         //关闭  
  133.         $("#cancel").click(function() {  
  134.             top.dialog.get("set-dialog").close().remove();  
  135.         });  
  136.     script>  
  137. body>  
  138. html>  

展示效果如下:

javaWeb用户权限控制简单实现_第3张图片

2) controller控制层用springmvc

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

[java]  view plain  copy
 
  1. /** 
  2.      * @fun 获取分店用户权限 
  3.      * @author 皮锋 
  4.      * @date 2016/8/25 
  5.      * @param session 
  6.      * @param id 
  7.      * @param substoreid 
  8.      * @return 
  9.      */  
  10.     @RequestMapping("getUserRightMaskById")  
  11.     @ResponseBody  
  12.     public Object getUserRightMaskById(HttpSession session,String id,String substoreid){  
  13.         substoreid=StringUtils.isEmpty(substoreid)?String.valueOf(session.getAttribute("substoreid")):substoreid;  
  14.         //判断是酒店还是客栈  
  15.         List> versionsList=this.setupService.getHotelHotelVersions(substoreid);  
  16.         Object versions=versionsList.get(0).get("versions");  
  17.         Map hotelMap=new HashMap();  
  18.         if((null!=versionsList)&&(versionsList.size()!=0)){  //list不为空  
  19.             if("complete".equals(versions)){   //酒店  
  20.                 //查询酒店权限树  
  21.                 hotelMap=this.rightMaskService.getUserRightMaskOnTree(substoreid,id,"complete");  
  22.             }else if("simple".equals(versions)){  //客栈  
  23.                 //查询客栈权限树  
  24.                 hotelMap=this.rightMaskService.getUserRightMaskOnTree(substoreid,id,"simple");  
  25.             }  
  26.         }  
  27.         Map resultMap = new HashMap();  
  28.         resultMap.put("datas", hotelMap);  
  29.           
  30.         return JSONObject.toJSONString(resultMap, SerializerFeature.WriteMapNullValue);  
  31.     }  

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

[java]  view plain  copy
 
  1. /** 
  2.      * @fun 获取分店用户权限 
  3.      * @author 皮锋 
  4.      * @date 2016/8/25 
  5.      * @param substoreid 
  6.      * @param id 
  7.      * @param versions 
  8.      * @return Map 
  9.      */  
  10.     @Override  
  11.     public Map getUserRightMaskOnTree(String substoreid, String id, String versions) {  
  12.         Map userRightMask=this.iRightMaskDao.getUserRightMaskBySubAndId(substoreid,id);  
  13.         List> listOne = new ArrayList>();  
  14.         List> listTwo = new ArrayList>();  
  15.         //List> listThree = new ArrayList>();  
  16.         List> resultList = new ArrayList>();  
  17.         if(versions.equals("complete")){  //酒店  
  18.             listOne = this.iRightMaskDao.getRightMaskOnHotelOne();  
  19.             listTwo = this.iRightMaskDao.getRightMaskOnHotelTwo();  
  20.             //listThree = this.iRightMaskDao.getRightMaskOnHotelThree();  
  21.             packagingToTwoTree(resultList,listOne,listTwo,userRightMask);  
  22.         }else if(versions.equals("simple")){  //客栈  
  23.             listOne = this.iRightMaskDao.getRightMaskOnTavernOne();  
  24.             listTwo = this.iRightMaskDao.getRightMaskOnTavernTwo();  
  25.             //listThree = this.iRightMaskDao.getRightMaskOnTavernThree();  
  26.             packagingToTwoTree(resultList,listOne,listTwo,userRightMask);  
  27.         }  
  28.         Map map = new HashMap();  
  29.         map.put("data", resultList);  
  30.         return map;  
  31.     }  
  32. /** 
  33.      * @function 封装一个一级树 
  34.      * @author 皮锋 
  35.      * @date 2016/8/26 
  36.      * @param resultList 
  37.      * @param listOne 
  38.      * @param authCode 
  39.      * @return void 
  40.      */  
  41.     private void packagingToOneTree(List> resultList,  
  42.             List> listOne, Map authCode) {  
  43.         for (int i = 0; i < listOne.size(); i++) {  
  44.             Map rootMap = new HashMap();  
  45.             rootMap.put("id", listOne.get(i).get("id"));  
  46.             rootMap.put("name", listOne.get(i).get("module"));  
  47.             if (validateRightMask(listOne, authCode, i) != -1) {  
  48.                 rootMap.put("checked"true);  
  49.             } else {  
  50.                 rootMap.put("checked"false);  
  51.             }  
  52.             resultList.add(rootMap);  
  53.         }  
  54.     }  
  55.   
  56.     /** 
  57.      * @function 封装一个二级树 
  58.      * @author 皮锋 
  59.      * @date 2016/8/26 
  60.      * @param resultList 
  61.      * @param listOne 
  62.      * @param listTwo 
  63.      * @param authCode 
  64.      * @return void 
  65.      */  
  66.     private void packagingToTwoTree(List> resultList,  
  67.             List> listOne,  
  68.             List> listTwo, Map authCode) {  
  69.         for (int i = 0; i < listOne.size(); i++) {  
  70.   
  71.             List> midList = new ArrayList>();  
  72.             for (int j = 0; j < listTwo.size(); j++) {  
  73.   
  74.                 if (listTwo.get(j).get("pid").toString()  
  75.                         .equals(listOne.get(i).get("id").toString())) {  
  76.   
  77.                     List> minlist = new ArrayList>();  
  78.   
  79.                     Map midMap = new HashMap();  
  80.                     midMap.put("id", listTwo.get(j).get("id"));  
  81.                     midMap.put("name", listTwo.get(j).get("module"));  
  82.                     midMap.put("children", minlist);  
  83.                     if (validateRightMask(listTwo, authCode, j) != -1) {  
  84.                         midMap.put("checked"true);  
  85.                     } else {  
  86.                         midMap.put("checked"false);  
  87.                     }  
  88.                     midList.add(midMap);  
  89.                 }  
  90.             }  
  91.             Map rootMap = new HashMap();  
  92.             rootMap.put("id", listOne.get(i).get("id"));  
  93.             rootMap.put("name", listOne.get(i).get("module"));  
  94.             rootMap.put("children", midList);  
  95.             if (validateRightMask(listOne, authCode, i) != -1) {  
  96.                 rootMap.put("checked"true);  
  97.             } else {  
  98.                 rootMap.put("checked"false);  
  99.             }  
  100.             resultList.add(rootMap);  
  101.         }  
  102.     }  
  103.   
  104.     /** 
  105.      * @function 封装一个三级树 
  106.      * @author 皮锋 
  107.      * @date 2016/8/26 
  108.      * @param resultList 
  109.      * @param listOne 
  110.      * @param listTwo 
  111.      * @param listThree 
  112.      * @param authCode 
  113.      * @return void 
  114.      */  
  115.     private void packagingToThreeTree(List> resultList,  
  116.             List> listOne,  
  117.             List> listTwo,  
  118.             List> listThree, Map authCode) {  
  119.         for (int i = 0; i < listOne.size(); i++) {  
  120.   
  121.             List> midList = new ArrayList>();  
  122.             for (int j = 0; j < listTwo.size(); j++) {  
  123.   
  124.                 if (listTwo.get(j).get("pid").toString()  
  125.                         .equals(listOne.get(i).get("id").toString())) {  
  126.   
  127.                     List> minlist = new ArrayList>();  
  128.   
  129.                     for (int k = 0; k < listThree.size(); k++) {  
  130.                         Map minMap = new HashMap();  
  131.                         if (listThree.get(k).get("pid").toString()  
  132.                                 .equals(listTwo.get(j).get("id").toString())) {  
  133.                             minMap.put("id", listThree.get(k).get("id"));  
  134.                             minMap.put("name", listThree.get(k).get("module"));  
  135.                             if (validateRightMask(listThree, authCode, k) != -1) {  
  136.                                 minMap.put("checked"true);  
  137.                             } else {  
  138.                                 minMap.put("checked"false);  
  139.                             }  
  140.                             minlist.add(minMap);  
  141.                         }  
  142.                     }  
  143.                     Map midMap = new HashMap();  
  144.                     midMap.put("id", listTwo.get(j).get("id"));  
  145.                     midMap.put("name", listTwo.get(j).get("module"));  
  146.                     midMap.put("children", minlist);  
  147.                     if (validateRightMask(listTwo, authCode, j) != -1) {  
  148.                         midMap.put("checked"true);  
  149.                     } else {  
  150.                         midMap.put("checked"false);  
  151.                     }  
  152.                     midList.add(midMap);  
  153.                 }  
  154.             }  
  155.             Map rootMap = new HashMap();  
  156.             rootMap.put("id", listOne.get(i).get("id"));  
  157.             rootMap.put("name", listOne.get(i).get("module"));  
  158.             rootMap.put("children", midList);  
  159.             if (validateRightMask(listOne, authCode, i) != -1) {  
  160.                 rootMap.put("checked"true);  
  161.             } else {  
  162.                 rootMap.put("checked"false);  
  163.             }  
  164.             resultList.add(rootMap);  
  165.         }  
  166.     }  
  167.   
  168.     /** 
  169.      * @function 验证authCode中是否有list中的权限码 
  170.      * @author 皮锋 
  171.      * @date 2016/8/26 
  172.      * @param list 
  173.      * @param authCode 
  174.      * @param i 
  175.      * @return int 
  176.      */  
  177.     private int validateRightMask(List> list,  
  178.             Map authCode, int i) {  
  179.         String rightMask = authCode.get("auth_code") != null ? authCode.get(  
  180.                 "auth_code").toString() : "";  
  181.         if (!StringUtils.isEmpty(rightMask)) {  
  182.             rightMask = rightMask.replace(";"",");  
  183.             String[] arry = rightMask.split(",");  
  184.             for (int j = 0; j < arry.length; j++) {  
  185.                 String arryRightMask = arry[j];  
  186.                 String listRightMask = list.get(i).get("id").toString();  
  187.                 if (arryRightMask.equals(listRightMask)) {  
  188.                     return 1;  
  189.                 }  
  190.             }  
  191.         } else {  
  192.             return -1;  
  193.         }  
  194.         return -1;  
  195.     }  

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.freemarkerxml文件中的配置

[html]  view plain  copy
 
  1. <bean id="freemarkerConfig"  
  2.           class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
  3.           
  4.         <property name="templateLoaderPath">  
  5.             <value>/WEB-INF/ftl/value>  
  6.         property>  
  7.         <property name="freemarkerVariables">  
  8.             <map>  
  9.                 <entry key="xml_escape" value-ref="fmXmlEscape"/>  
  10.             map>  
  11.         property>  
  12.         <property name="freemarkerSettings">  
  13.             <props>  
  14.                 <prop key="tag_syntax">auto_detectprop>  
  15.                 <prop key="template_update_delay">0prop>  
  16.                 <prop key="default_encoding">UTF-8prop>  
  17.                 <prop key="output_encoding">UTF-8prop>  
  18.                 <prop key="locale">zh_CNprop>  
  19.                 <prop key="date_format">yyyy-MM-ddprop>  
  20.                 <prop key="time_format">HH:mm:ssprop>  
  21.                 <prop key="number_format">0.######prop>  
  22.                 <prop key="datetime_format">yyyy-MM-dd HH:mm:ssprop>  
  23.                   
  24.                 <prop key="classic_compatible">trueprop>  
  25.                   
  26.                 <prop key="auto_import">inc/spring.ftl as baseprop>  
  27.             props>  
  28.         property>  
  29.     bean>  
  30.   
  31.     <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>  
  32.   
  33.     <bean id="freeMarkerViewResolver"  
  34.           class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
  35.         <property name="suffix" value=".html"/>  
  36.         <property name="cache" value="false"/>  
  37.         <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>  
  38.         <property name="contentType" value="text/html;charset=UTF-8">property>  
  39.           
  40.         <property name="allowSessionOverride" value="true"/>  
  41.         <property name="exposeRequestAttributes" value="true"/>  
  42.         <property name="exposeSessionAttributes" value="true"/>  
  43.         <property name="exposeSpringMacroHelpers" value="true"/>  
  44.           
  45.         <property name="requestContextAttribute" value="request"/>  
  46.           
  47.         <property name="attributesMap">    
  48.             <map>    
  49.                     
  50.                 <entry key="menucall">    
  51.                         
  52.                     <bean class="com.leike.util.MenuFunction" />    
  53.                 entry>    
  54.             map>    
  55.         property>    
  56.     bean>  

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

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

[java]  view plain  copy
 
  1. public class MenuFunction implements TemplateMethodModel{  
  2.     @Override  
  3.     public Object exec(List arg0) throws TemplateModelException {   
  4.         int level = Integer.valueOf(arg0.get(0).toString()); //模块等级  
  5.         int modelId=Integer.valueOf(arg0.get(1).toString()); //模块id  
  6.         int count=0//记录session是否有此模块的权限码  
  7.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();  
  8.         HttpSession session=request.getSession();  
  9.         Object o = session.getAttribute("info");  
  10.         if(o==null)  
  11.             return false;  
  12.         Info info = (Info) o;  
  13.         String authCode=info.getUser().getAuthCode(); //权限码  
  14.         if(authCode.contains(";")){  
  15.             String[] masks=authCode.split(";");  
  16.             String[]  m=masks[level].split(",");  
  17.             for (int i = 0; i < m.length; i++) {  
  18.                 if(modelId==Integer.parseInt(m[i])){  
  19.                     ++count;  
  20.                 }else{  
  21.                     count+=0;  
  22.                 }  
  23.             }  
  24.         }  
  25.         if(count==0){  
  26.             return false;  
  27.         }else{  
  28.             return true;  
  29.         }  
  30.           
  31.     }  
  32.   
  33. }  

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

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

例如:

[html]  view plain  copy
 
  1. <#if menucall(1,122)>  
  2.     <li style="line-height: 250%">  
  3.         <a href="#" id="booknew"><i class="glyphicon">i>预订a>  
  4.     li>  
  5. #if>  




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

你可能感兴趣的:(java,web,权限,权限控制)