1、項目環境:
①、web+shiro
②、添加資源文件shiro.ini
[users]
admin=hello
login=java
③、進行shiro的認證編寫:本次的操作一定要通過shiro.ini文件進行信息的取得;
如果要想進行shiro的認證信息的讀取,那麼首先需要使用一個org.apache.shiro.util.Factory接口,在這個接口裏面定義有取得一個SecuruityManager接口對象的方法:public T getInstance();
|-此方法可以取得一個org.apache.shiro.mgt.SecurityManager接口對象;
|-Factory是接口,本次將通過一個ini文件進行讀取,所以應該使用“org.apache.shiro.config.IniSecurityManagerFactory”,子類,這個子類裏面只需要關注構造方法:public IniSecurityManagerFactory(String iniResourcePath),資源定位通過classpath取得:
// 取得Factory接口對象,主要的目的是通過配置文件加載文件之中的信息,這些信息暫時不能夠成爲認證信息
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
Factory接口中保管的是SecurityManager接口對象,是進行所有認證信息的處理的,讀取進來的資源文件在個接口裏面將轉換爲認證數據(用戶名、密碼):
// 取得裏面所保存的所有的認證數據信息
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
具體的認證信息一定要通過Subject接口來實現,而SecurityManager只是一個綜合的認證信息集合。
所以爲了解決這個問題可以使用“org.apache.shiro.SecurityUtils”,在這個類中有如下兩個方法:
|-設置SecurityManager接口對象:public static void setSecurityManager(SecurityManager securityManager);
|-取得一個要進行認證的Subject接口:public static Subject getSubject();
// 利用一個專門的認證操作的處理類,實現認證處理的具體的實現 SecurityUtils.setSecurityManager(securityManager);
// 獲取進行用戶名和密碼認證的接口對象 Subject subject = SecurityUtils.getSubject() ;
本次使用的是用戶名和密碼的組合進行的認證處理,所以需要將用戶名和密碼包裝爲一個Token,因爲在Subject接口下定義有如下的方法:
|-登錄驗證:public void login(AuthenticationToken token) throws AuthenticationException;
|-登錄註銷:public void logout()。
使用“org.apache.shiro.authc.UsernamePasswordToken”,只需要創建這個類的對象,創建的時候傳遞用戶名和密碼即可實現;
// 定義了一個Token,裏面保存要登錄的用戶名和密碼信息 UsernamePasswordToken token = new UsernamePasswordToken("admin","hello") ;
利用Subject實現用戶的登錄處理操作:
public class TestLoginDemo {
public static void main(String[] args) {
// 取得Factory接口對象,主要的目的是通過配置文件加載文件之中的信息,這些信息暫時不能夠成爲認證信息
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
// 取得裏面所保存的所有的認證數據信息
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
// 利用一個專門的認證操作的處理類,實現認證處理的具體的實現 SecurityUtils.setSecurityManager(securityManager);
// 獲取進行用戶名和密碼認證的接口對象 Subject subject = SecurityUtils.getSubject() ;
// 定義了一個Token,裏面保存要登錄的用戶名和密碼信息
UsernamePasswordToken token = new UsernamePasswordToken("admin","hello") ;
// 實現用戶登錄處理
subject.login(token);
System.out.println(subject.getPrincipal()); // 取得用戶名
}
}
在保證用戶名和密碼正確的前提下就可以輕鬆的實現登錄控制,而如果說你的用戶名或密碼出現了錯誤,那麼程序就將拋出異常,實際上異常的內容比較多:
· 密碼輸入錯誤,但是用戶名正確:
Exception in thread "main" org.apache.shiro.authc.IncorrectCredentialsException:
Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - admin, rememberMe=false] did not match the expected credentials.
用戶名錯誤,密碼輸入正確:
Exception in thread "main" org.apache.shiro.authc.UnknownAccountException:
Realm [org.apache.shiro.realm.text.IniRealm@136432db] was unable to find account data for the submitted AuthenticationToken [org.apache.shiro.authc.UsernamePasswordToken - xx,rememberMe=false].
在shiro裏面如果賬戶出現了錯誤,那麼密碼將不會驗證,對於這一點一定要清楚,否則在使用自定義數據庫認證的時候流程上就會出現問題。
在整個程序裏面,必須要進行驗證數據的信息加載,而後所有的認證信息交由SecuritManager 管理,而用戶要想進行用戶名或密碼的認證操作必須通過Subject 接口完成,隨後使用AuthenticationToken 保存所有的認證信息,本處爲普通的用戶名和密碼,所以使用了一個UsernamePasswordToken 子類進行配置。
如果登錄成功則不會拋出異常,如果登錄失敗,則會根據失敗的類型拋出不同的異常子類。