<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何設計一個通用的權限管理系統(tǒng)?說的太詳細了!

          共 10231字,需瀏覽 21分鐘

           ·

          2021-04-06 22:02

          「今日推薦」

          【開源項目】高仿抖音項目 就問你服不?
          沉入海底 2 年的微軟數(shù)據(jù)中心浮出水面:故障率只有陸地上的 1/8
          騰訊,干掉 Redis 項目,正式開源、太牛逼啦!


          一個系統(tǒng),如果沒有安全控制,是十分危險的,一般安全控制包括身份認證和權限管理。用戶訪問時,首先需要查看此用戶是否是合法用戶,然后檢查此用戶可以對那些資源進行何種操作,最終做到安全訪問。身份認證的方式有很多種,最簡單的就是直接用戶名密碼,還有業(yè)內比較通用的方式CAS方式登陸等;授權的框架也很多,比如OAuth2,Shiro等。本文首先會講解一下CAS的概念,以及基于角色的權限管理模型(RBAC)的概念,接著進行數(shù)據(jù)表的設計,最后講解如何利用Shiro進行權限管理。

          一、CAS身份認證

          集中式認證服務(英語:Central Authentication Service,縮寫CAS)是一種針對萬維網(wǎng)的單點登錄協(xié)議。它的目的是允許一個用戶訪問多個應用程序,而只需提供一次憑證。

          1.1、名詞概念

          CAS的核心就是其Ticket,及其在Ticket之上的一系列處理操作。CAS的主要票據(jù)有TGT、ST、PGT、PGTIOU、PT,其中TGT、ST是CAS1.0(基礎模式)協(xié)議中就有的票據(jù),PGT、PGTIOU、PT是CAS2.0(代理模式)協(xié)議中有的票據(jù)。這些票據(jù)誰生成得了?肯定是有相關服務的,主要服務有:KDC,AS,TGS。兩者媒介肯定也是有的:TGC。

          1.1.1、CAS的Ticket

          1)TGT(Ticket Granting Tieckt)

          TGT是CAS(具體為 KDC 的 AS 發(fā)放)為用戶簽發(fā)的登錄票據(jù),擁有了TGT,用戶就可以證明自己在CAS成功登錄過。TGT封裝了Cookie值以及此Cookie值對應的用戶信息。用戶在CAS認證成功后,CAS生成cookie,寫入瀏覽器,同時生成一個TGT對象,放入自己的緩存,TGT對象的ID就是cookie的值。當HTTP再次請求到來時,如果傳過來的有CAS生成的cookie,則CAS以此cookie值為key查詢緩存中有無TGT ,如果有的話,則說明用戶之前登錄過,如果沒有,則用戶需要重新登錄。

          簡而言之,即獲取這樣一張票據(jù)后,以后申請各種其他服務票據(jù) (ST) 便不必再向 KDC 提交身份認證信息 ( 準確術語是 Credentials) 。

          2)ST(Service ticket)

          ST是CAS(由 KDC 的 TGS 發(fā)放)為用戶簽發(fā)的訪問某一service的票據(jù)。

          用戶訪問service時,service發(fā)現(xiàn)用戶沒有ST,則要求用戶去CAS獲取ST。用戶向CAS發(fā)出獲取ST的請求,如果用戶的請求中包含cookie,則CAS會以此cookie值為key查詢緩存中有無TGT,如果存在TGT,則用此TGT簽發(fā)一個ST,返回給用戶。用戶憑借ST去訪問service,service拿ST去CAS驗證,驗證通過后,允許用戶訪問資源。

          任何一臺 Workstation 都需要擁有一張有效的 Service Ticket 才能訪問域內部的應用 (Applications) 。如果能正確接收 Service Ticket ,說明在 CASClient-CASServer 之間的信任關系已經(jīng)被正確建立起來。

          3)PGT(Proxy Granting Ticket)

          Proxy Service的代理憑據(jù)。用戶通過CAS成功登錄某一Proxy Service后,CAS生成一個PGT對象,緩存在CAS本地,同時將PGT的值(一個UUID字符串)回傳給Proxy Service,并保存在Proxy Service里。Proxy Service拿到PGT后,就可以為Target Service(back-end service)做代理,為其申請PT。

          4)PT(Proxy Ticket)

          PT是用戶訪問Target Service(back-end service)的票據(jù)。如果用戶訪問的是一個Web應用,則Web應用會要求瀏覽器提供ST,瀏覽器就會用cookie去CAS獲取一個ST,然后就可以訪問這個Web應用了。如果用戶訪問的不是一個Web應用,而是一個C/S結構的應用,因為C/S結構的應用得不到cookie,所以用戶不能自己去CAS獲取ST,而是通過訪問proxy service的接口,憑借proxy service的PGT去獲取一個PT,然后才能訪問到此應用。

          TGT、ST、PGT、PT之間關系的總結

          1:ST是TGT簽發(fā)的。用戶在CAS上認證成功后,CAS生成TGT,用TGT簽發(fā)一個ST,ST的ticketGrantingTicket屬性值是TGT對象,然后把ST的值redirect到客戶應用。

          2:PGT是ST簽發(fā)的。用戶憑借ST去訪問Proxy service,Proxy service去CAS驗證ST(同時傳遞PgtUrl參數(shù)給CAS),如果ST驗證成功,則CAS用ST簽發(fā)一個PGT,PGT對象里的ticketGrantingTicket是簽發(fā)ST的TGT對象。

          3:PT是PGT簽發(fā)的。Proxy service代理back-end service去CAS獲取PT的時候,CAS根據(jù)傳來的pgt參數(shù),獲取到PGT對象,然后調用其grantServiceTicket方法,生成一個PT對象。

          1.1.2、CAS的服務

          CAS的主要服務有:

          • KDC(Key Distribution Center );
          • AS(Authentication Service)它索取 Crendential,發(fā)放 TGT;
          • TGS(Ticket  Granting Service),索取 TGT ,發(fā)放 ST。

          1.1.3、CAS的媒介

          TGC(Ticket Granting Cookie)

          存放用戶身份認證憑證的cookie,在瀏覽器和CAS Server間通訊時使用,并且只能基于安全通道傳輸(Https),是CAS Server用來明確用戶身份的憑證。

          1.2、CAS工作原理

          CAS的單點登錄的認證過程,所用應用服務器受到應用請求后,檢查ST和TGT,如果沒有或不對,轉到CAS認證服務器登錄頁面,通過安全認證后得到ST和TGT,再重新定向到相關應用服務器,在回話生命周期之內如果再定向到別的應用,將出示ST和TGT進行認證,注意,取得TGT的過程是通過SSL安全協(xié)議的。

          從網(wǎng)上找了一個比較專業(yè)又比較詳細的CAS工作原理流程圖:

          CAS流程

          專業(yè)版可能比較晦澀難懂,來個通俗版。通俗形象地說就是:相當于用戶要去游樂場,首先要在門口檢查用戶的身份 ( 即 CHECK 用戶的 ID 和 PASS), 如果用戶通過驗證,游樂場的門衛(wèi) (AS) 即提供給用戶一張門卡 (TGT)。

          這張卡片的用處就是告訴游樂場的各個場所,用戶是通過正門進來,而不是后門偷爬進來的,并且也是獲取進入場所一把鑰匙。

          現(xiàn)在用戶有張卡,但是這對用戶來不重要,因為用戶來游樂場不是為了拿這張卡的而是為了游覽游樂項目,這時用戶摩天樓,并想游玩。

          這時摩天輪的服務員 (client) 攔下用戶,向用戶要求摩天輪的 (ST) 票據(jù),用戶說用戶只有一個門卡 (TGT), 那用戶只要把 TGT 放在一旁的票據(jù)授權機 (TGS) 上刷一下。

          票據(jù)授權機 (TGS) 就根據(jù)用戶現(xiàn)在所在的摩天輪,給用戶一張摩天輪的票據(jù) (ST), 這樣用戶有了摩天輪的票據(jù),現(xiàn)在用戶可以暢通無阻的進入摩天輪里游玩了。

          當然如果用戶玩完摩天輪后,想去游樂園的咖啡廳休息下,那用戶一樣只要帶著那張門卡 (TGT). 到相應的咖啡廳的票據(jù)授權機 (TGS) 刷一下,得到咖啡廳的票據(jù) (ST) 就可以進入咖啡廳

          當用戶離開游樂場后,想用這張 TGT 去刷打的回家的費用,對不起,用戶的 TGT 已經(jīng)過期了,在用戶離開游樂場那刻開始,用戶的 TGT 就已經(jīng)銷毀了 。

          二、基于角色的權限管理模型

          在業(yè)界接受度較高的權限模型是RBAC(Role-Based Access Control),基本的概念是將“角色”這個概念賦予用戶,在系統(tǒng)中用戶通過分配角色從而獲得相應的權限,一個用戶可以有多個角色,一個角色可以有多個權限,從而實現(xiàn)權限的靈活配置。

          2.1、基本的RBAC模型

          最基本的RBAC模型,就是由“用戶”,“角色”以及“權限”這三個主體組成,一個用戶可以有多個角色,一個角色可以有多個權限,他們之間的關系可以是多對一關系,也可以是多對多關系。

          用戶角色權限關系

          2.2、引入用戶組的RBAC模型

          如果用戶數(shù)量比較龐大,新增一個角色時,需要為大量用戶都重新分配一遍新的角色,工程量巨大,此時可以引入用戶組的概念。如果部分用戶的使用場景是相對一致和基礎的,可以把這些用戶打包成一個組,基于這個組的對象進行角色和權限的賦予。最終用戶擁有的所有權限 = 用戶個人擁有的權限+該用戶所在用戶組擁有的權限。

          2.3、角色分級的RBAC模型

          在一些業(yè)務場景中,上層角色需要繼承下層角色的全部權限,此時則需要使用角色繼承的RBAC模型。此時除了對角色進行定義,還需要管理角色間的關系,通過關系來體現(xiàn)角色的層級關系,從而達到繼承權限的效果。角色的繼承關系主有兩種:樹形圖和有向無環(huán)圖。

          角色繼承模式

          繼承關系常常來源于公司團隊的組織架構,此時常常將角色與組織結構進行關聯(lián)達到繼承角色模型的效果。

          2.4、角色限制的RBAC模型

          在一些產(chǎn)品或系統(tǒng)中,部分角色可能是需要隔離的、不允許被同時賦予一個人的,比如不能既是運動員又是裁判員。因此,有些角色存在互拆關系。此外,限制還可能是數(shù)量上的,比如某個產(chǎn)品組中有且只有一個管理員,不允許刪除或再分配其他管理員。

          根據(jù)不同的業(yè)務需求,限制的形式很多,需要注意的是不能僅僅依賴后段限制,而是要在前端展示清晰的規(guī)則和恰當?shù)南拗疲苊庥脩舫鲥e。

          2.5、權限管理的基本元素

          權限管理的基本元素為:用戶,角色,資源,操作,權限。

          1、用戶 應用系統(tǒng)的具體操作者,用戶可以自己擁有權限信息,可以歸屬于0~n個角色,可屬于0~n個組。他的權限集是自身具有的權限、所屬的各角色具有的權限、所屬的各組具有的權限的合集。它與權限、角色、組之間的關系都是n對n的關系。

          2、用戶組(可選) 為了更好地管理用戶,對用戶進行分組歸類,簡稱為用戶分組。組也具有上下級關系,可以形成樹狀視圖。在實際情況中,我們知道,組也可以具有自己的角色信息、權限信息。

          3、角色 為了對許多擁有相似權限的用戶進行分類管理,定義了角色的概念,例如系統(tǒng)管理員、管理員、用戶、訪客等角色。角色具有上下級關系,可以形成樹狀視圖,父級角色的權限是自身及它的所有子角色的權限的綜合。父級角色的用戶、父級角色的組同理可推。

          4、資源 權限管理的一個單元實體對象,我們廣義的稱之為資源,可以是一個人,也可以是一個產(chǎn)品,一個文件,一個頁面 等等。5、操作 對資源進行的實際操作,比如讀、寫、編輯等等。

          6、權限 資源+操作,構成一個權限控制點。

          對象間的關系包括:

          • 是否關系
          • 繼承關系
          • 限制關系(互斥、范圍限制、邊界限制、字段限制)

          三、數(shù)據(jù)表設計

          按照RBAC模型,數(shù)據(jù)庫可以這樣設計:

          1、產(chǎn)品表(t_product_info)

          字段名稱字段類型備注
          產(chǎn)品Idpro_idint(11)自增
          產(chǎn)品名稱(英)name_envarchar(50)not null
          產(chǎn)品名層(中)name_chvarchar(50)not null
          創(chuàng)建人creatorvarchar(50)not null
          所屬人ownervarchar(50)not null
          描述descriptionvarchar(255)
          創(chuàng)建時間create_timetimestampnot null

          2、產(chǎn)品成員表(t_product_member)

          字段名稱字段類型備注
          記錄IDidint(11)自增
          產(chǎn)品IDpro_idint(11)fk:t_produck_info
          成員IDmember_idint(11)not null
          創(chuàng)建時間create_timetimestampnot null

          3、用戶信息表(t_user_info)

          字段名稱字段類型備注
          用戶IDuser_idint(11)not null
          英文名nike_namevarchar(10)not null
          中文名real_namevarchar(10)not null
          創(chuàng)建時間create_timetimestampnot null
          更新時間update_timetimestampnot null

          4、用戶角色表(t_user_role)

          字段名稱字段類型備注
          記錄IDidint(11)自增
          用戶IDuser_idint(11)not null
          角色IDrole_idvarchar(50)not null
          創(chuàng)建時間create_timetimestampnot null

          5、角色表(t_role)

          字段名稱字段類型備注
          記錄IDidint(11)自增
          角色IDrole_idvarchar(50)not null,比如:A~USER
          角色名稱role_namevarchar(50)not null
          對象objectvarchar(50)not null
          對象IDobject_idvarchar(50)not null
          角色備注commentvarchar(255)
          創(chuàng)建時間create_timetimestampnot null

          6、基礎角色表(t_role_base)

          字段名稱字段類型備注
          記錄IDidint(11)自增
          角色IDrole_idvarchar(50)not null,比如:A~USER
          角色名稱role_namevarchar(50)not null
          角色備注commentvarchar(255)
          權限permissionvarchar(255)not null
          創(chuàng)建時間create_timetimestampnot null

          7、角色權限表(t_role_permission)

          字段名稱字段類型備注
          記錄IDidint(11)自增
          角色IDrole_idvarchar(50)fk:t_role->role_id
          權限permissionvarchar(255)not null
          基礎角色IDrole_base_idvarchar(50)fk:t_role_base->role_id
          創(chuàng)建時間create_timetimestampnot null

          8、用戶組表(t_user_group,可選)

          字段名稱字段類型備注
          組IDidint(11)自增
          組名稱group_namevarchar(50)not null
          組描述group_descvarchar(255)not null
          創(chuàng)建時間create_timetimestampnot null

          9、組角色表(t_user_group_role,可選)

          字段名稱字段類型備注
          記錄IDidint(11)自增
          組IDrole_idvarchar(50)not null
          角色IDrole_idvarchar(255)not null
          創(chuàng)建時間create_timetimestampnot null

          10、用戶權限表(t_user_permission,可選)

          字段名稱字段類型備注
          記錄IDidint(11)自增
          用戶IDrole_idvarchar(50)not null
          權限permissionvarchar(255)not null
          創(chuàng)建時間create_timetimestampnot null

          四、角色及權限點設計

          權限控制的整個過程可以描述為:“誰”對“什么”進行什么”操作",從而,引出我們需要做的工作有:角色設計,資源定義,以及對資源的操作定義。再詳細描述下,鑒權就是根據(jù)用戶身份(角色)獲得其對那些資源,可以進行什么操作,其中對資源的操作做為一個獨立的權限體。

          4.1、定義系統(tǒng)中的用戶角色

          一般是采用“通用角色+實例角色”的模式,實例角色可繼承通用角色,從而擁有通用角色的權限。

          常見的通用角色定義:ADMIN、MANAGER、MEMBER、GUEST 常見角色權限分配:1)SUPER_ADMIN,具有系統(tǒng)一切權限 1)產(chǎn)品ADMIN,具有當前產(chǎn)品所有權限;2)產(chǎn)品MANAGER,不具備刪除權限,可修改,添加成員等 3)產(chǎn)品MEMEBER,可查看,修改信息,不可添加成員;4)產(chǎn)品GUEST,只可查看

          實例角色:實例角色一般可以這樣定義:“資源點+通用角色+資源ID”

          注:其中資源可能是產(chǎn)品,可能是頁面,也可能是菜單等

          4.2、定義系統(tǒng)中的資源以及操作

          一般系統(tǒng)中的最常見資源就是:產(chǎn)品(P) 一般對資源的主要操作包括:增加(CREATE)、刪除(DELETE)、修改(EDIT)、查看(VIEW)

          當然,系統(tǒng)中的資源肯定不止產(chǎn)品,同時產(chǎn)品這個粒度有些太粗,還可以更細化控制,當然一切都根據(jù)實際業(yè)務需求情況定義相應的資源點和操作。

          4.3、權限體策略

          權限控制策略采用五元組,如下:

          資源:操作:實例:BU:密級

          其中,資源可以是人,也可以是一個需求,一個文件等等;操作為對資源的操作;實例極為產(chǎn)品ID或者用戶ID;BU,密級用于控制不同BU,不同保密模塊的可見性

          五、身份認證加權限管理實施

          JAVA可以采用SHIRO框架,一個最簡單的一個Shiro應用:1)應用代碼通過subject授權,而subject又委托給SecurityManager;2)我們需要給Shiro的security注入Realm,從而讓SecurityManager能得到合法的用戶及其權限進行判斷;

          Shiro的最主要要做的工作其實就是兩個:身份認證和權限校驗,下面分別進行介紹。

          5.1、身份認證

          通過前面的文章分析,我們知道自定義身份校驗校驗邏輯,只需要繼承AuthenticatingRealm即可,Override如下接口進行身份認證:

          @Override
          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){}
          復制代碼

          上面這個接口,參數(shù)AuthenticationToken,它可以自定義子類實現(xiàn),框架提供的有:UsernamePasswordToken,CasToken。

          如果是采用用戶名密碼方式登陸,那么就構造一個UsernamePasswordToken,然后取數(shù)據(jù)查詢用戶名密碼是否有效;如果是采用的CAS方式登陸,那么就通過ticket構造一個CasToken,然后與CAS服務交互驗證ticket是否有效。如果驗證通過會生成一個AuthenticationInfo。此時身份認證完成。

          最簡單的用戶密碼登陸身份校驗代碼 CAS方式驗證首先得有CAS系統(tǒng),這里就不說明CAS方式怎么驗證了,說一下怎么用用戶密碼登陸進行身份校驗,認證流程都一樣

          自定義一個AuthenticatingRealm:

          public class MyRealm1 implements AuthenticatingRealm {  
              @Override
            protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
                  String username = (String)token.getPrincipal();  //得到用戶名 
                  String password = new String((char[])token.getCredentials()); //得到密碼  
                  //取數(shù)據(jù)庫中看用戶名是否有效
                  //checkUserInfo();
                  
                  //如果身份認證驗證成功,返回一個AuthenticationInfo實現(xiàn);  
                  return new SimpleAuthenticationInfo(username, password, getName());  
              }  
          }  
          復制代碼

          5.2、權限校驗

          權限校驗主要要做的事情就是完成"從數(shù)據(jù)庫中查出用戶所擁有的所有權限是否包含當前待校驗的權限"這么一個判斷過程,因此主要要做的就是:1)從數(shù)據(jù)庫中查出用戶所擁有的所有權限;2)解析權限,看看是否包含待校驗的權限。

          1、第一步:獲取用戶權限信息 獲取用戶權限信息這個過程是在Realm中完成的,繼承AuthorizingRealm,然后Override如下兩個接口獲取用戶的權限信息:

          //獲取用戶身份信息,Authorization前需要先獲取用戶身份信息
          @Override
          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){}

          //獲取用戶權限信息
          @Override
          protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection){
          }
          復制代碼

          權限信息查詢過程一般為:1)從數(shù)據(jù)庫中讀區(qū)用戶自身所配權限;2)從數(shù)據(jù)庫中讀取用戶角色所用擁有的權限(角色包含實例角色和BASE角色) 3)用戶最終的權限:用戶自身權限+用戶角色權限

          2、第二步:權限校驗

          1)如果通過角色校驗,則調用hasRole,與傳入的角色比較即可;

          2)如果通過權限體校驗,則調用isPermitted(...),與傳入的權限進行比較即可。

          shiro內部邏輯如下:首先通過PermissionResolver將權限字符串轉換成相應的Permission實例,默認使用WildcardPermissionResolver,即轉換為通配符的WildcardPermission;接著調用Permission.implies(Permission p)逐個與傳入的權限比較,如果有匹配的則返回true,否則false。

          六、參考資料

          https://shiro.apache.org/

          https://github.com/apache/shiro

          https://jinnianshilongnian.iteye.com/blog/2018398

          https://my.oschina.net/bochs/blog/2248956

          https://blog.itning.top/posts/Essays/20190408-A-brief-explanation-of-single-sign-on-SSO-and-centralized-authentication-service-CAS-and-open-authorized-OAuth.html

          來源:https://juejin.im/post/6850037267554287629


          END
          最近熬夜給大家準備了515套Java代碼,有一些是業(yè)務類的小項目,比如Java博客項目,也有腳手架、也有平時用一些的工具類、21套小程序代碼,也有一些游戲類的項目。

          掃以下二維碼并回復“828”即可獲取


          如下圖所示

          瀏覽 23
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月婷婷激情视频 | 中文字幕综合 | 日本黄色视频在线免费观看 | 影音先锋久久久久AV综合网成人 | 欧美精品亚洲精品日韩已满 |