日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权

發(fā)布時(shí)間:2024/9/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、Shiro授權(quán):

1、授權(quán)與權(quán)限:

(1)授權(quán):訪問控制,必須具有該資源的訪問權(quán)限才可以訪問該資源。

(2)權(quán)限模型:標(biāo)準(zhǔn)權(quán)限數(shù)據(jù)模型包括 :用戶、角色、權(quán)限(包括資源和權(quán)限)、用戶角色關(guān)系、角色權(quán)限關(guān)系。

(3)權(quán)限分配:通過UI界面方便給用戶分配權(quán)限,對上邊權(quán)限模型進(jìn)行增、刪、改、查操作。

(4)權(quán)限控制:

第一種:基于角色的權(quán)限控制:根據(jù)角色判斷是否有操作權(quán)限,因?yàn)榻巧淖兓暂^高,如果角色修改需要修改控制代碼,系統(tǒng)可擴(kuò)展性不強(qiáng)。

第二種:基于資源的權(quán)限控制:根據(jù)資源權(quán)限判斷是否有操作權(quán)限,因?yàn)橘Y源較為固定,如果角色修改或角色中權(quán)限修改不需要修改控制代碼,使用此方法系統(tǒng)可維護(hù)性很強(qiáng)。建議使用。

(5)權(quán)限管理的解決方案:

①對于粗顆粒權(quán)限管理,建議在系統(tǒng)架構(gòu)層面去解決,寫系統(tǒng)架構(gòu)級(jí)別統(tǒng)一代碼(基礎(chǔ)代碼)。

粗顆粒權(quán)限:比如對系統(tǒng)的url、菜單、jsp頁面、頁面上按鈕、類方法進(jìn)行權(quán)限管理,即對資源類型進(jìn)行權(quán)限管理。

②對于細(xì)顆粒權(quán)限管理:細(xì)顆粒權(quán)限管理是系統(tǒng)的業(yè)務(wù)邏輯,業(yè)務(wù)邏輯代碼不方便抽取統(tǒng)一代碼,建議在系統(tǒng)業(yè)務(wù)層進(jìn)行處理。

粗顆粒權(quán)限:比如用戶id為001的用戶信息(資源實(shí)例)、類型為t01的商品信息(資源實(shí)例),對資源實(shí)例進(jìn)行權(quán)限管理,可以理解為對數(shù)據(jù)級(jí)別的權(quán)限管理。

?

2、授權(quán)流程:

(1)對subject進(jìn)行授權(quán),調(diào)用方法isPermitted("permission串");

(2)SecurityManager執(zhí)行授權(quán),通過ModularRealmAuthorizer執(zhí)行授權(quán);

(3)ModularRealmAuthorizer執(zhí)行realm(自定義的CustomRealm)從數(shù)據(jù)庫查詢權(quán)限數(shù)據(jù),調(diào)用realm的授權(quán)方法:doGetAuthorizationInfo;

(4)realm從數(shù)據(jù)庫查詢權(quán)限數(shù)據(jù),返回ModularRealmAuthorizer;

(5)ModularRealmAuthorizer調(diào)用PermissionResolver進(jìn)行權(quán)限串比對;

(6)如果比對后,isPermitted中"permission串"在realm查詢到權(quán)限數(shù)據(jù)中,說明用戶訪問permission串有權(quán)限,否則 沒有權(quán)限,拋出異常。

?

3、Shiro 支持三種方式的授權(quán):

(1)編程式:通過寫if/else 授權(quán)代碼塊完成:

Subject subject = SecurityUtils.getSubject();

if(subject.hasRole(“admin”)) {

//有權(quán)限

} else {

//無權(quán)限

}

(2)注解式:通過在執(zhí)行的Java方法上放置相應(yīng)的注解完成:

@RequiresRoles("admin")

public void hello() {

//有權(quán)限

}

(3)JSP/GSP 標(biāo)簽:在JSP/GSP 頁面通過相應(yīng)的標(biāo)簽完成:

<shiro:hasRole name="admin">

<!— 有權(quán)限—>

</shiro:hasRole>

?

?

二、Shiro授權(quán)示例程序:

1、入門的Shiro授權(quán)程序:

(1)編寫shiro-permission.ini文件:

shiro-permission.ini文件里邊的內(nèi)容相當(dāng)于在數(shù)據(jù)庫查詢出來的;

#用戶 [users] #用戶zhangsan的密碼是123,此用戶具有role1和role2兩個(gè)角色 zhangsan=123456,role1,role2 wangwu=123456,role2#權(quán)限 [roles] #角色role1對資源user擁有create、update權(quán)限 role1=user:create,user:update role2=user:create,items:delete role3=user:create

權(quán)限標(biāo)識(shí)符號(hào)規(guī)則:資源:操作:實(shí)例(中間使用半角:分隔)

user:create:01? 表示對用戶資源的01實(shí)例進(jìn)行create操作。

user:create? ? 表示對用戶資源進(jìn)行create操作,相當(dāng)于user:create:*,對所有用戶資源實(shí)例進(jìn)行create操作。

user:*:01? 表示對用戶資源實(shí)例01進(jìn)行所有操作。

(2)程序編寫:

//shiro的授權(quán)測試: public class AuthorizationTest {//角色授權(quán)、資源授權(quán)測試:@Testpublic void testAuthorization(){Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123456");try {subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}System.out.println("認(rèn)證狀態(tài):" + subject.isAuthenticated());//認(rèn)證通過之后執(zhí)行授權(quán)://基于角色的授權(quán)//hasRole傳入角色標(biāo)識(shí):boolean ishasRole = subject.hasRole("role1");System.out.println("單個(gè)角色判斷" + ishasRole);//hasAllRoles是否擁有多個(gè)角色:boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1","role2","role3"));System.out.println("多個(gè)角色判斷" + hasAllRoles);// 使用check方法進(jìn)行授權(quán),如果授權(quán)不通過會(huì)拋出異常subject.checkRole("role2");//基于資源的授權(quán)://isPermitted傳入權(quán)限標(biāo)識(shí)符boolean isPermitted = subject.isPermitted("user:create:1");System.out.println("單個(gè)權(quán)限判斷" + isPermitted);boolean isPermittedAll = subject.isPermittedAll("user:create:1","user:delete");System.out.println("多個(gè)權(quán)限判斷" + isPermittedAll);// 使用check方法進(jìn)行授權(quán),如果授權(quán)不通過會(huì)拋出異常subject.checkPermission("items:delete:1");} }

(3)執(zhí)行結(jié)果:

至此,Shiro授權(quán)入門程序就完成了。在這個(gè)程序中,我們讀取的是在shiro.ini配置文件中靜態(tài)配置好的權(quán)限內(nèi)容,但是在實(shí)際開發(fā),我們通常是從數(shù)據(jù)庫中查詢用戶所擁有的權(quán)限信息,因此,我們需要使用自定義的Realm進(jìn)行從數(shù)據(jù)庫中查詢用戶的權(quán)限信息。

?

2、自定義realm進(jìn)行授權(quán):

上面的程序是通過shiro-permission.ini對權(quán)限文件進(jìn)行靜態(tài)配置,在實(shí)際開發(fā)中,都是從數(shù)據(jù)庫中獲取權(quán)限數(shù)據(jù)。就需要自定義realm,由realm從數(shù)據(jù)庫查詢權(quán)限數(shù)據(jù)。

realm根據(jù)用戶身份查詢權(quán)限數(shù)據(jù),將權(quán)限數(shù)據(jù)返回給authorizer(授權(quán)器)。

(1)自定義realm:

//自定義的Realm,需要繼承AuthorizingRealm,并且重寫這個(gè)類的兩個(gè)方法 public class CustomRealm extends AuthorizingRealm{// 設(shè)置realm的名稱@Overridepublic void setName(String name) {super.setName("customRealm");}// 用于授權(quán)@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//從principals獲取身份信息//將getPrimaryPrincipal方法返回值轉(zhuǎn)為真實(shí)身份(在上邊的doGetAuthenticationInfo認(rèn)證通過填充到SimpleAuthenticationInfo中的身份類型)String userCode = (String) principals.getPrimaryPrincipal();//根據(jù)身份信息獲取權(quán)限信息//連接數(shù)據(jù)庫//模擬從數(shù)據(jù)庫獲取到數(shù)據(jù)List<String> permissions = new ArrayList<String>();permissions.add("user:create");//用戶的創(chuàng)建permissions.add("items:add");//商品添加權(quán)限//查到權(quán)限數(shù)據(jù),返回授權(quán)信息(要包括上邊的permissions)SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();//將上邊查詢到授權(quán)信息填充到simpleAuthorizationInfo對象中simpleAuthorizationInfo.addStringPermissions(permissions);return simpleAuthorizationInfo;} }

(2)編寫shiro-realm.ini文件:

在shiro-realm.ini文件中配置自定義的realm,將realm設(shè)置到securityManager中。

[main] #自定義的realm customRealm=com.zwp.shiro.realm.CustomRealm #將realm設(shè)置到securityManager,相當(dāng)于spring中的注入 securityManager.realms=$customRealm

(3)測試:

// 自定義realm進(jìn)行資源授權(quán)測試@Testpublic void testAuthorizationCustomRealm() {Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");SecurityManager securityManager = factory.getInstance();SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();// 創(chuàng)建token令牌UsernamePasswordToken token = new UsernamePasswordToken("zhangsan","123456");// 執(zhí)行認(rèn)證try {subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}System.out.println("認(rèn)證狀態(tài):" + subject.isAuthenticated());// 認(rèn)證通過后執(zhí)行授權(quán)// 基于資源的授權(quán),調(diào)用isPermitted方法會(huì)調(diào)用CustomRealm從數(shù)據(jù)庫查詢正確權(quán)限數(shù)據(jù)// isPermitted傳入權(quán)限標(biāo)識(shí)符,判斷user:create:1是否在CustomRealm查詢到權(quán)限數(shù)據(jù)之內(nèi)boolean isPermitted = subject.isPermitted("user:create:1");System.out.println("單個(gè)權(quán)限判斷" + isPermitted);boolean isPermittedAll = subject.isPermittedAll("user:create:1","user:create");System.out.println("多個(gè)權(quán)限判斷" + isPermittedAll);// 使用check方法進(jìn)行授權(quán),如果授權(quán)不通過會(huì)拋出異常subject.checkPermission("items:add:1");}

(4)測試結(jié)果:

至此,Shiro使用自定義Realm進(jìn)行授權(quán)的程序就完成了。

?

與50位技術(shù)專家面對面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的Shiro框架:授权流程、授权方式、Shiro授权入门程序、自定义Realm进行授权的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。