高级第八天:RBAC

RBAC

主要内容

1.RBAC的介绍

2.传统项目数据库设计方案

3.RBAC设计方案

4.RBAC的详细版本

5.URL权限控制

一.RBAC简介

[1]RBAC的概念

基于角色的权限访问控制(Role-Based Access Control)作为传动访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注.在RBAC中,权限与角色相关连,用户通过称为适当角色的成员而得到这些角色的权限.这就极大的简化了权限的管理rbac:一种数据库设计思想,根据设计数据库设计方案,完成项目的权限控制

[2]权限的使用情景

2.1不同用户登录后看到的菜单是不一样的

2.2不同用户看到的页面效果不一样

2.2.1有的用户可以看到"授权"按钮,或有的用户可以看见"删除"按钮

2.3不同用户完成的功能是不一样的

2.3.1有的用户可以执行删除,有的可以执行新增

2.4场景示意图

小公司和比较简单的权限系统使用的基于用户的访问控制如下

这种访问控制只适用于操作人员比较少的系统,如果操作人员较多,对每个操作人员都进行授权操作,无疑是非常繁琐的.所以我们就需要基于角色的访问控制

[3]学习RBAC需要掌握的要素

3.1如何设计数据库中表

3.2如何根据数据库完成项目

3.3RBAC核心是角色,在数据库设计时一定有角色

3.4根据RBAC设计思想,设计出来的方案是非常灵活的

二.实现技术设计方案

[1]需求实现方案一

使用C:if判断的方式进行实现,和中级书写的SXTOA一样,在left中动态的判断该用户下的标签即可

缺点:

    (1)所有的菜单标签必须提前的书写好.不可以更改

    (2)如果需要添加菜单,只能更改源代码

[2]需求实现方案二

数据库结构实现如图所示

缺点:

(1)新建一个用户时,在用户表中添加一条数据

(2)新建一个用户时,在关联表中添加N条数据

(3)每次新建一个用户需要添加:1+N(关联几个)条数据

[3]需求实现方案三

1.基于RBAC的设计方案

1.1设定好在某些情况下哪些菜单需要被关联

1.1.1例如:管理员可以看到所有菜单

1.1.2例如:销售总监可以看到"销售管理"菜单

1.1.3例如:普通员工只能看见系统公告中公告查看

2.2现实生活中的职位对应1个或多个数据库中的角色

2.在系统上线后,会在程序中添加几种比较常见的角色,并把菜单和角色关联

3.1以后每次新建用户时

3.2在用户表中添加一个数据

3.3在用户和角色关联表中添加1条或n条数据

3.画图说明RBAC:


三.RBAC具体实现

[1]实现需求

使用RBAC数据库设计思想,完成不同的用户登录系统后显示不同的菜单

[2]功能分析

用户:张三和李四

菜单

用户管理

    用户查询

    增加用户

班级管理

    班级查询

    增加班级

查看通告

    系统设置

[3]数据库设计

[4]数据库Sql语句

/*用户表--新增角色rid*/

/**角色表**/

create table role(

    rid INT(5) PRIMARY KEY AUTO_INCREMENT,

    rname VARCHAR(55)

);

INSERT INTO role VALUES(DEFAULT,'管理员工');

INSERT INTO role VALUES(DEFAULT,'管理员');

/**菜单表**/

CREATE TABLE menu(

    mmid INT(5) PRIMARY KEY AUTO_INCREMENT,

    mname VARCHAR(55),

    URL varchar(55),

    pid INT(5)

);

/**角色-菜单表**/

create table role_menu(

    rid INT(5),

    MMID INT(5)

);

/*给不同的角色赋予菜单*/

insert into role_menu values(1,2);

insert into role_menu values(1,3);


insert into role_menu values(1,6);

insert into role_menu values(1,8);

insert into role_menu values(1,9);

insert into role_menu values(1,10);


insert into role_menu values(2,1);

insert into role_menu values(2,2);

insert into role_menu values(2,3);

insert into role_menu values(2,4);

insert into role_menu values(2,5);

insert into role_menu values(2,6);

insert into role_menu values(2,7);

insert into role_menu values(2,8);

insert into role_menu values(2,9);

insert into role_menu values(2,10);

/*用户登录成功查询该角色下的所有菜单 用户登录成功就知道了rid=1*/

/*在role_menu表中查询指定角色中所有菜单的id*/

select mmid from role_menu where rid=1

/*在去menu表中查询指定mmid对应的菜单*/

select * from menu where mmid in(select mmid from role_menu where rid=2)and pid=1

[5]代码效果实现

5.1登录jsp页面

<div style="margin-top:120px; margin-left:407px;">

    <div id="di" class="easyui-panel" title="登录" style="width:400px;height:300px;data-options="iconCls:'icon-help',closable:false,collapsible:false,minimizable:true,maximizable:true">

        <div style="text-align:center;margin-top:80px;">

            <form>

                <div style="margin-bottom:25px;">

                    <span>用户名</span>

                    <input type="text" name="name" class="easyui-textbox" data-opyions="required:true"/>

                </div>

                <div style="margin-botton:25px;">

                    <span>密&nbsp;&nbsp码</span>

                    <input type="text" name="pwd" class="easyui-passwordbox" data-options="required:true"/>

                </div>

                <div>

                    <a onclick="javascript:void(0)" class="easyui-linkbutton" data-options="inonCls:'icon-clear'">提交</a>

                    <a onclick="javascript:void(0)" class="easyui-linkbutton" data-options="inonCls:'icon-clear'">清空</a>

                </div>

            </form>

        </div>

    </div>

</div>

5.2Mapper层代码

//查询菜单操作

@Select("select * from menu where mmid in(select mmid from role_menu where rid=#{param1}) and pid=#{param2}")

List<Menu> selectMore(int rid,int pid);

5.3Service层代码

@Override

public List<Tree>findMoreMenu(int rid,int pid){

    List<Menu>list = menuMapper.selectMore(rid,pid);

    List<Tree> lsit2 = new ArrayList<>();

    for(Menu menu:list){

        Tree tree = new Tree(menu.getMmid(),menu.getMname(),menu.getState()==1?"open":"closed");

        //把指定的url地址保存到tree

        tree.setUrl(menu.getUrl());

        list2.add(tree);

    }

    return list2;

}

5.4Controller层代码

@RequestMappoing("/findMoreMenus")

public List<Tree>findMoreMenus(@RequestParam(defaultValue="0")int id,HttpSession session){

    User user = (User)session.getAttribute("user");

    return menuService.findMoreMenu(user.getRid(),id);

}

5.5运行截图

四.RBAC详细版本

[1]数据库设计

1.1权限表:平时小型项目中可以省略

1.2用户组表:对用户进行分组,每个用户组绑定多个角色,把用户放入到用户组后,具有对应多个角色

1.3角色组:角色组对应多个角色,用户组和角色组

1.4完成访问控制时,需要对什么类型表进行访问控制(在简单版中)把需要控制的内容和角色进行直接关联

[2]详细版中是跟权限进行关联

五.URL权限控制

1.目前的问题

访问通过URL非法操作,例如:在浏览器中直接通过URL访问控制器

2.解决方案

区分开:和页面元素可见权限

2.1页面元素可见:在页面能不能看到某些内容

2.2URL权限指:在浏览器地址栏直接访问

3.实现思想(基于简单版)

3.1添加URL表:

3.2URL表和角色表进行关联

3.3在filter或拦截器中天啊及权限验证

4.代码实现实例

4.1数据库设计

在当前rbac案例中新增一张url权限信息表

表名:t_url

作用:存储需要被管理的url地址信息

字段:编号,url地址

在当前rbac案例中新增一张角色和url权限表的关联表

表名:r_url

作用:存储需要被管理的url地址和信息

字段:编号,url地址

在当前rbac案例总新增一张角色和url权限表的关联表

表名:r_url

作用:表名url和角色之间的关联关系

字段:角色id,url的编号

Sql语句实例:

4.2代码实现

实现思路:

在项目增加过滤器,在过滤器中判断当前请求的url地址和用户具备的操作的URL地址是否一致.如果一致则放行,不一致则拦截,并提示器权限不足

过滤器代码示例:

public class LoginFilter2 implements Filter{

    @Override

    public void init(FilterConfig filterConfig)throws ServletException{

    }

    @Override

    public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)throws IOException,ServletException{

        //登录权限的校验

        HttpServeltRequest req = (HttpServletRequest)servletRequest;

        HttpServletResponse resp = (HttpServletResponse)servletResponse;

        //获取用户输入的名称

        String uri = req.getRequestURI();

        if("/ty/login.jsp".equals(uri)||"/ty/UserController/userLogin".equals(uri)){

            filterChain.doFilter(req,resp);

        }else{

            User user = (User)req.getSession().getAttribute("user");

            if(user!=null){

                List<Url>list = user.getList();

                for(Url u:lsit){

                    String url = "/ty/u.getUrl()";

                    System.out.println(url);

                    if(uri.equals(url)){

                        fileterChain.deFilter(req,resp);

                        return;

                    }

                }

                resp.getWriter().print("<script type='text/javascript'>alert('ERROR')</script>")

            }else{

                //判断当前请求是否是ajax请求

                if("XMLHttpRequest".equals(req.getheader("X-Requested-With"))){

                    System.out.println("ajax中Session跳转页面");

                    resp.setHeader("sessionstatus","timeout");

                    resp.setHeader("redirectUrl","/ty/login.jsp");

                }else{

                    resp.sendRedirect("/ty/loging.jsp");

                }

            }

        }

    }

    @Override

    public void destrop(){}

}

页面引入jquery ajax请求的通用代码(特定ajax请求处理后执行)

$.ajaxSetup({

    contextType:"application/x-www-form-urlencoded;charset=utf-8",

    complete:function(XMLHttpRequest,textStatus){

        //通过XNLHttpRequest取得响应头,sessionstatus

        var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");

        if(sessionstatus=="timeout"){

            //这里怎么处理在你,这里跳转的登录页面

            window.location.replace(XMLHttpRequest.getResponseHeader("redirectUrl"));

        }

    }

})

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349