shiro的 認證 與 授權
1,什麽是shiro
Shiro是apache旗下一個開源框架,它將軟件系統的安全認證相關的功能抽取出來,實現用戶身份認證,權限授權、加密、會話管理等功能,組成了一個通用的安全認證框架。
shiro將安全認證相關的功能抽取出來組成一個框架,使用shiro就可以非常快速的完成認證、授權等功能的開發,降低系統成本。shiro使用廣泛,shiro可以運行在web應用,非web應用,集群分布式應用中越來越多的用戶開始使用shiro。 java領域中spring security(原名Acegi)也是一個開源的權限管理框架,但是spring security依賴spring運行,而shiro就相對獨立,最主要是因為shiro使用簡單、靈活,所以現在越來越多的用戶選擇shiro。
2、shiro的認證
(1)認證流程
(2)程序實現
1:、加入所需jat包
2、加入log4j日誌文件
3、編寫shiro.ini
[users]
zhang=123
lisi=123
4、認證代碼
@Test public void testLoginLogout() { // 構建SecurityManager工廠,IniSecurityManagerFactory可以從ini文件中初始化SecurityManager環境 Factory<SecurityManager> factory = newIniSecurityManagerFactory( "classpath:shiro.ini"); // 通過工廠創建SecurityManager SecurityManager securityManager = factory.getInstance(); // 將securityManager設置到運行環境中 SecurityUtils.setSecurityManager(securityManager); // 創建一個Subject實例,該實例認證要使用上邊創建的securityManager進行Subject subject = SecurityUtils.getSubject(); // 創建token令牌,記錄用戶認證的身份和憑證即賬號和密碼 UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { // 用戶登陸 subject.login(token); } catch (AuthenticationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 用戶認證狀態 Boolean isAuthenticated = subject.isAuthenticated(); System.out.println("用戶認證狀態:" + isAuthenticated); // 用戶退出 subject.logout(); isAuthenticated = subject.isAuthenticated(); System.out.println("用戶認證狀態:" + isAuthenticated); }
(3)認證執行流程
1、 創建token令牌,token中有用戶提交的認證信息即賬號和密碼
2、 執行subject.login(token),最終由securityManager通過Authenticator進行認證
3、 Authenticator的實現ModularRealmAuthenticator調用realm從ini配置文件取用戶真實的賬號和密碼,這裏使用的是IniRealm(shiro自帶)
4、 IniRealm先根據token中的賬號去ini中找該賬號,如果找不到則給ModularRealmAuthenticator返回null,如果找到則匹配密碼,匹配密碼成功則認證通過。
3、shiro的授權
(1)執行流程
(2)授權方式
Shiro 支持三種方式的授權:
1、 編程式:通過寫if/else 授權代碼塊完成:
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole(“admin”)) {
//有權限
} else {
//無權限
}
/2、 註解式:通過在執行的Java方法上放置相應的註解完成:
@RequiresRoles("admin")
public void hello() {
//有權限
}
/3、 JSP/GSP 標簽:在JSP/GSP 頁面通過相應的標簽完成:
<shiro:hasRole name="admin">
<!— 有權限—>
</shiro:hasRole>
(3)授權測試
1、shiro.ini
[users]
#用戶zhang的密碼是123,此用戶具有role1和role2兩個角色
zhang=123,role1,role2
wang=123,role2
[roles]
#角色role1對資源user擁有create、update權限
role1=user:create,user:update
#角色role2對資源user擁有create、delete權限
role2=user:create,user:delete
#角色role3對資源user擁有create權限
role3=user:create
2、測試代碼
@Test public void testPermission() { // 從ini文件中創建SecurityManager工廠 Factory<SecurityManager> factory = new IniSecurityManagerFactory( "classpath:shiro-permission.ini"); // 創建SecurityManager SecurityManager securityManager = factory.getInstance(); // 將securityManager設置到運行環境 SecurityUtils.setSecurityManager(securityManager); // 創建主體對象 Subject subject = SecurityUtils.getSubject(); // 對主體對象進行認證 // 用戶登陸 // 設置用戶認證的身份(principals)和憑證(credentials) UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { subject.login(token); } catch (AuthenticationException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 用戶認證狀態 Boolean isAuthenticated = subject.isAuthenticated(); System.out.println("用戶認證狀態:" + isAuthenticated); // 用戶授權檢測 基於角色授權 // 是否有某一個角色 System.out.println("用戶是否擁有一個角色:" + subject.hasRole("role1")); // 是否有多個角色 System.out.println("用戶是否擁有多個角色:" + subject.hasAllRoles(Arrays.asList("role1", "role2"))); // subject.checkRole("role1"); // subject.checkRoles(Arrays.asList("role1", "role2")); // 授權檢測,失敗則拋出異常 // subject.checkRole("role22"); // 基於資源授權 System.out.println("是否擁有某一個權限:" + subject.isPermitted("user:delete")); System.out.println("是否擁有多個權限:" + subject.isPermittedAll("user:create:1", "user:delete")); //檢查權限 subject.checkPermission("sys:user:delete"); subject.checkPermissions("user:create:1","user:delete"); }
3、
shiro的 認證 與 授權