高級第八天:RBAC

RBAC

主要內(nèi)容

1.RBAC的介紹

2.傳統(tǒng)項(xiàng)目數(shù)據(jù)庫設(shè)計(jì)方案

3.RBAC設(shè)計(jì)方案

4.RBAC的詳細(xì)版本

5.URL權(quán)限控制

一.RBAC簡介

[1]RBAC的概念

基于角色的權(quán)限訪問控制(Role-Based Access Control)作為傳動(dòng)訪問控制(自主訪問,強(qiáng)制訪問)的有前景的代替受到廣泛的關(guān)注.在RBAC中,權(quán)限與角色相關(guān)連,用戶通過稱為適當(dāng)角色的成員而得到這些角色的權(quán)限.這就極大的簡化了權(quán)限的管理rbac:一種數(shù)據(jù)庫設(shè)計(jì)思想,根據(jù)設(shè)計(jì)數(shù)據(jù)庫設(shè)計(jì)方案,完成項(xiàng)目的權(quán)限控制

[2]權(quán)限的使用情景

2.1不同用戶登錄后看到的菜單是不一樣的

2.2不同用戶看到的頁面效果不一樣

2.2.1有的用戶可以看到"授權(quán)"按鈕,或有的用戶可以看見"刪除"按鈕

2.3不同用戶完成的功能是不一樣的

2.3.1有的用戶可以執(zhí)行刪除,有的可以執(zhí)行新增

2.4場景示意圖

小公司和比較簡單的權(quán)限系統(tǒng)使用的基于用戶的訪問控制如下

這種訪問控制只適用于操作人員比較少的系統(tǒng),如果操作人員較多,對每個(gè)操作人員都進(jìn)行授權(quán)操作,無疑是非常繁瑣的.所以我們就需要基于角色的訪問控制

[3]學(xué)習(xí)RBAC需要掌握的要素

3.1如何設(shè)計(jì)數(shù)據(jù)庫中表

3.2如何根據(jù)數(shù)據(jù)庫完成項(xiàng)目

3.3RBAC核心是角色,在數(shù)據(jù)庫設(shè)計(jì)時(shí)一定有角色

3.4根據(jù)RBAC設(shè)計(jì)思想,設(shè)計(jì)出來的方案是非常靈活的

二.實(shí)現(xiàn)技術(shù)設(shè)計(jì)方案

[1]需求實(shí)現(xiàn)方案一

使用C:if判斷的方式進(jìn)行實(shí)現(xiàn),和中級書寫的SXTOA一樣,在left中動(dòng)態(tài)的判斷該用戶下的標(biāo)簽即可

缺點(diǎn):

? ? (1)所有的菜單標(biāo)簽必須提前的書寫好.不可以更改

? ? (2)如果需要添加菜單,只能更改源代碼

[2]需求實(shí)現(xiàn)方案二

數(shù)據(jù)庫結(jié)構(gòu)實(shí)現(xiàn)如圖所示

缺點(diǎn):

(1)新建一個(gè)用戶時(shí),在用戶表中添加一條數(shù)據(jù)

(2)新建一個(gè)用戶時(shí),在關(guān)聯(lián)表中添加N條數(shù)據(jù)

(3)每次新建一個(gè)用戶需要添加:1+N(關(guān)聯(lián)幾個(gè))條數(shù)據(jù)

[3]需求實(shí)現(xiàn)方案三

1.基于RBAC的設(shè)計(jì)方案

1.1設(shè)定好在某些情況下哪些菜單需要被關(guān)聯(lián)

1.1.1例如:管理員可以看到所有菜單

1.1.2例如:銷售總監(jiān)可以看到"銷售管理"菜單

1.1.3例如:普通員工只能看見系統(tǒng)公告中公告查看

2.2現(xiàn)實(shí)生活中的職位對應(yīng)1個(gè)或多個(gè)數(shù)據(jù)庫中的角色

2.在系統(tǒng)上線后,會(huì)在程序中添加幾種比較常見的角色,并把菜單和角色關(guān)聯(lián)

3.1以后每次新建用戶時(shí)

3.2在用戶表中添加一個(gè)數(shù)據(jù)

3.3在用戶和角色關(guān)聯(lián)表中添加1條或n條數(shù)據(jù)

3.畫圖說明RBAC:


三.RBAC具體實(shí)現(xiàn)

[1]實(shí)現(xiàn)需求

使用RBAC數(shù)據(jù)庫設(shè)計(jì)思想,完成不同的用戶登錄系統(tǒng)后顯示不同的菜單

[2]功能分析

用戶:張三和李四

菜單

用戶管理

? ? 用戶查詢

? ? 增加用戶

班級管理

? ? 班級查詢

? ? 增加班級

查看通告

? ? 系統(tǒng)設(shè)置

[3]數(shù)據(jù)庫設(shè)計(jì)

[4]數(shù)據(jù)庫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對應(yīng)的菜單*/

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

[5]代碼效果實(shí)現(xiàn)

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運(yùn)行截圖

四.RBAC詳細(xì)版本

[1]數(shù)據(jù)庫設(shè)計(jì)

1.1權(quán)限表:平時(shí)小型項(xiàng)目中可以省略

1.2用戶組表:對用戶進(jìn)行分組,每個(gè)用戶組綁定多個(gè)角色,把用戶放入到用戶組后,具有對應(yīng)多個(gè)角色

1.3角色組:角色組對應(yīng)多個(gè)角色,用戶組和角色組

1.4完成訪問控制時(shí),需要對什么類型表進(jìn)行訪問控制(在簡單版中)把需要控制的內(nèi)容和角色進(jìn)行直接關(guān)聯(lián)

[2]詳細(xì)版中是跟權(quán)限進(jìn)行關(guān)聯(lián)

五.URL權(quán)限控制

1.目前的問題

訪問通過URL非法操作,例如:在瀏覽器中直接通過URL訪問控制器

2.解決方案

區(qū)分開:和頁面元素可見權(quán)限

2.1頁面元素可見:在頁面能不能看到某些內(nèi)容

2.2URL權(quán)限指:在瀏覽器地址欄直接訪問

3.實(shí)現(xiàn)思想(基于簡單版)

3.1添加URL表:

3.2URL表和角色表進(jìn)行關(guān)聯(lián)

3.3在filter或攔截器中天啊及權(quán)限驗(yàn)證

4.代碼實(shí)現(xiàn)實(shí)例

4.1數(shù)據(jù)庫設(shè)計(jì)

在當(dāng)前rbac案例中新增一張url權(quán)限信息表

表名:t_url

作用:存儲(chǔ)需要被管理的url地址信息

字段:編號,url地址

在當(dāng)前rbac案例中新增一張角色和url權(quán)限表的關(guān)聯(lián)表

表名:r_url

作用:存儲(chǔ)需要被管理的url地址和信息

字段:編號,url地址

在當(dāng)前rbac案例總新增一張角色和url權(quán)限表的關(guān)聯(lián)表

表名:r_url

作用:表名url和角色之間的關(guān)聯(lián)關(guān)系

字段:角色id,url的編號

Sql語句實(shí)例:

4.2代碼實(shí)現(xiàn)

實(shí)現(xiàn)思路:

在項(xiàng)目增加過濾器,在過濾器中判斷當(dāng)前請求的url地址和用戶具備的操作的URL地址是否一致.如果一致則放行,不一致則攔截,并提示器權(quán)限不足

過濾器代碼示例:

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{

? ? ? ? //登錄權(quán)限的校驗(yàn)

? ? ? ? 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{

? ? ? ? ? ? ? ? //判斷當(dāng)前請求是否是ajax請求

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

? ? ? ? ? ? ? ? ? ? System.out.println("ajax中Session跳轉(zhuǎn)頁面");

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

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

????????????????}else{

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

????????????????}

????????????}

????????}

????}

? ? @Override

? ? public void destrop(){}

}

頁面引入jquery ajax請求的通用代碼(特定ajax請求處理后執(zhí)行)

$.ajaxSetup({

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

? ? complete:function(XMLHttpRequest,textStatus){

? ? ? ? //通過XNLHttpRequest取得響應(yīng)頭,sessionstatus

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

? ? ? ? if(sessionstatus=="timeout"){

? ? ? ? ? ? //這里怎么處理在你,這里跳轉(zhuǎn)的登錄頁面

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

? ? ? ? }

????}

})

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。