shiro教程(3)-shiro授权
1?shiro授權(quán)
1.1?授權(quán)流程
1.2?授權(quán)方式
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>
本教程序授權(quán)測試使用第一種編程方式,實(shí)際與web系統(tǒng)集成使用后兩種方式。
1.3?授權(quán)測試
1.3.1?shiro-permission.ini
創(chuàng)建存放權(quán)限的配置文件shiro-permission.ini,如下:
[users] #用戶zhang的密碼是123,此用戶具有role1和role2兩個(gè)角色 zhang=123,role1,role2 wang=123,role2[roles] #角色role1對(duì)資源user擁有create、update權(quán)限 role1=user:create,user:update #角色role2對(duì)資源user擁有create、delete權(quán)限 role2=user:create,user:delete #角色role3對(duì)資源user擁有create權(quán)限 role3=user:create在ini文件中用戶、角色、權(quán)限的配置規(guī)則是:“用戶名=密碼,角色1,角色2...” “角色=權(quán)限1,權(quán)限2...”,首先根據(jù)用戶名找角色,再根據(jù)角色找權(quán)限,角色是權(quán)限集合。
1.3.2?權(quán)限字符串規(guī)則
權(quán)限字符串的規(guī)則是:“資源標(biāo)識(shí)符:操作:資源實(shí)例標(biāo)識(shí)符”,意思是對(duì)哪個(gè)資源的哪個(gè)實(shí)例具有什么操作,“:”是資源/操作/實(shí)例的分割符,權(quán)限字符串也可以使用*通配符。
例子:
用戶創(chuàng)建權(quán)限:user:create,或user:create:*
用戶修改實(shí)例001的權(quán)限:user:update:001
用戶實(shí)例001的所有權(quán)限:user:*:001
1.3.3?測試代碼
測試代碼同認(rèn)證代碼,注意ini地址改為shiro-permission.ini,主要學(xué)習(xí)下邊授權(quán)的方法,注意:在用戶認(rèn)證通過后執(zhí)行下邊的授權(quán)代碼。
@Testpublic void testPermission() {// 從ini文件中創(chuàng)建SecurityManager工廠Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");// 創(chuàng)建SecurityManagerSecurityManager securityManager = factory.getInstance();// 將securityManager設(shè)置到運(yùn)行環(huán)境SecurityUtils.setSecurityManager(securityManager);// 創(chuàng)建主體對(duì)象Subject subject = SecurityUtils.getSubject();// 對(duì)主體對(duì)象進(jìn)行認(rèn)證// 用戶登陸// 設(shè)置用戶認(rèn)證的身份(principals)和憑證(credentials)UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");try {subject.login(token);} catch (AuthenticationException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 用戶認(rèn)證狀態(tài)Boolean isAuthenticated = subject.isAuthenticated();System.out.println("用戶認(rèn)證狀態(tài):" + isAuthenticated);// 用戶授權(quán)檢測 基于角色授權(quán)// 是否有某一個(gè)角色System.out.println("用戶是否擁有一個(gè)角色:" + subject.hasRole("role1"));// 是否有多個(gè)角色System.out.println("用戶是否擁有多個(gè)角色:" + subject.hasAllRoles(Arrays.asList("role1", "role2")));//subject.checkRole("role1");//subject.checkRoles(Arrays.asList("role1", "role2"));// 授權(quán)檢測,失敗則拋出異常// subject.checkRole("role22");// 基于資源授權(quán)System.out.println("是否擁有某一個(gè)權(quán)限:" + subject.isPermitted("user:delete"));System.out.println("是否擁有多個(gè)權(quán)限:" + subject.isPermittedAll("user:create:1","user:delete"));//檢查權(quán)限subject.checkPermission("sys:user:delete");subject.checkPermissions("user:create:1","user:delete");}1.3.4?基于角色的授權(quán)
// 用戶授權(quán)檢測 基于角色授權(quán)// 是否有某一個(gè)角色System.out.println("用戶是否擁有一個(gè)角色:" + subject.hasRole("role1"));// 是否有多個(gè)角色System.out.println("用戶是否擁有多個(gè)角色:" + subject.hasAllRoles(Arrays.asList("role1", "role2")));對(duì)應(yīng)的check方法:
subject.checkRole("role1");
subject.checkRoles(Arrays.asList("role1","role2"));
上邊check方法如果授權(quán)失敗則拋出異常:
org.apache.shiro.authz.UnauthorizedException: Subject does not have role [.....]1.3.5?基于資源授權(quán)
// 基于資源授權(quán)System.out.println("是否擁有某一個(gè)權(quán)限:" + subject.isPermitted("user:delete"));System.out.println("是否擁有多個(gè)權(quán)限:" + subject.isPermittedAll("user:create:1","user:delete"));對(duì)應(yīng)的check方法:subject.checkPermission("sys:user:delete");subject.checkPermissions("user:create:1","user:delete");上邊check方法如果授權(quán)失敗則拋出異常:
org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [....]1.4?自定義realm
與上邊認(rèn)證自定義realm一樣,大部分情況是要從數(shù)據(jù)庫獲取權(quán)限數(shù)據(jù),這里直接實(shí)現(xiàn)基于資源的授權(quán)。
1.4.1?realm代碼
在認(rèn)證章節(jié)寫的自定義realm類中完善doGetAuthorizationInfo方法,此方法需要完成:根據(jù)用戶身份信息從數(shù)據(jù)庫查詢權(quán)限字符串,由shiro進(jìn)行授權(quán)。
// 授權(quán)@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {// 獲取身份信息String username = (String) principals.getPrimaryPrincipal();// 根據(jù)身份信息從數(shù)據(jù)庫中查詢權(quán)限數(shù)據(jù)//....這里使用靜態(tài)數(shù)據(jù)模擬List<String> permissions = new ArrayList<String>();permissions.add("user:create");permissions.add("user.delete");//將權(quán)限信息封閉為AuthorizationInfoSimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();for(String permission:permissions){simpleAuthorizationInfo.addStringPermission(permission);}return simpleAuthorizationInfo;}1.4.2?shiro-realm.ini
ini配置文件還使用認(rèn)證階段使用的,不用改變。
1.4.3?測試代碼
同上邊的授權(quán)測試代碼,注意修改ini地址為shiro-realm.ini。
1.4.4?授權(quán)執(zhí)行流程
1、?執(zhí)行subject.isPermitted("user:create")
2、?securityManager通過ModularRealmAuthorizer進(jìn)行授權(quán)
3、?ModularRealmAuthorizer調(diào)用realm獲取權(quán)限信息
4、ModularRealmAuthorizer再通過permissionResolver解析權(quán)限字符串,校驗(yàn)是否匹配
?
總結(jié)
以上是生活随笔為你收集整理的shiro教程(3)-shiro授权的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shiro教程(2)- shiro介绍
- 下一篇: shiro教程(4)-shiro与项目集