之前一直在用shiro開發,不過只是會使用,並沒有深入了解,最近有時間學習了一下,把最近學習所得分享一下。
shiro簡介
Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼和會話管理。使用Shiro的易於理解的API,您可以快速、輕松地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序,
相比於spring security更加的簡潔和使用方便了。
三個核心組件
組件看不懂可以先把demo跑起來,然后回頭再看,慢慢的體會就明白了。
Subject:代表了當前訪問系統的用戶,不一定是人,也可以是爬蟲等其他東西。
SecurityManager:安全管理器,是shiro框架的核心。管理者subject,session等。
Realms:可以看成是一個權限的數據源,用戶登錄認證和授權都是通過realm來進行的,可以設置多個realm。
第一個demo
添加pom文件
<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.2</version> </dependency>
在classpath下新增一個shiro.ini文件。文件內容如下:(意思就是在這個系統中存在zhang這個用戶,密碼是123,后期會用存儲在數據庫中的賬戶密碼,這里方便測試和講解。。)
[users]
zhang=123
測試代碼:
Factory<SecurityManager> factory =new IniSecurityManagerFactory("classpath:shiro.ini"); //得到安全管理器 SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { subject.login(token); } catch (AuthenticationException e) { e.printStackTrace(); } System.out.println(subject.isAuthenticated()); subject.logout(); System.out.println(subject.isAuthenticated());
最后輸出
true
false。
1首先通過IniSecurityManagerFactory和shiro.ini文件生成一個SecurityManager工廠。
2獲得該工廠的實例並托管給SecurityUtils這個類,其實就是放在了SecurityUtils這個類的一個static變量中,下面操作的底層還是SecurityManager里面的方法。
3通過SecurityUtils得到一個主體對象,此時這個對象里面是沒有數據的,也沒有通過認證和授權,在SecurityUtils.getSubject獲取的同時將當這個subject綁定到了當前線程里面。(如果你再getSubject也是該subject)
4創建一個token綁定用戶名和密碼。然后調用subject.login進行登錄(其實就是調用了SecurityManager進行認證和授權)
shiro核心架構圖:

Authentication:身份認證,通常用於校驗密碼等操作。
Authorization:授權,權限驗證,校驗用戶是否擁有某種角色,或者某種更細的資源。
創建SecurityManager步驟
我們創建Security對象在java環境下創建了DefalutSecurityManager,它默認繼承了AuthenticatingSecurityManager(認證器管理器),AuthorizingSecurityManager(授權器管理器)。

這兩個管理器分別持有Authenticator(認證器)和Authorizer(授權器)兩個變量。(這里只貼圖一張,還有一個可以看看源碼)

這兩個在java環境下的實現類分別是,ModularRealmAuthenticator(默認認證器)和ModularRealmAuthorizer(默認授權器)
並且在讀取shiro.ini文件后默認創建了IniRealm對象,注入到上面的認證器和授權器中。(授權器也有個realms對象,realms存放着賬號密碼,對應的權限等信息)

最后創建了一個SecurityManager對象。
在調用subject.login(token);方法時候。會最終調用這個安全管理器的認證器對應的方法。

登錄的時候如果賬號密碼異常,會拋出對應的異常。(這里還綁定了session,shiro的session和web中的session是兩個概念,后面介紹)
到這里這個zhang的subject就登錄成功了。
github地址
https://github.com/cmniefei/shiroparent
