前言
本文主要講解shiro的具體認證機制,這屬於shiro提供的一個最基本的功能。
Authentication首先有兩個重要的概念:
- Principals : 是用來標識Subject身份的屬性,可以是用戶名、身份證號等值。需要注意的Shiro中最好用用戶名、郵箱或者用戶id作爲主要標識Principal。
- Credentials : 是針對Principal具有的特定憑證,通常來說可能是密碼。
Principal/Credential對組成了一個Subject用來作爲認證主題,並且通常是 用戶名/密碼的形式。
具體認證步驟
添加依賴
<dependencies>
<!--shiro核心-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.1</version>
</dependency>
<!--測試-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
配置【ini】
這邊配置了兩個用戶
[users]
rose = 123
joe = 123456
核心代碼
public class AuthenticationUtil {
//日誌
private static final Logger logger = LoggerFactory.getLogger(AuthenticationUtil.class);
public static void authenticate(String username, String password) {
// 通過加載shiro.ini配置文件獲取IniSecurityManagerFactory實例工廠,然後調用getInstance()獲取SecurityManager實例
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager = factory.getInstance();
//設置全局共享
SecurityUtils.setSecurityManager(securityManager);
//獲取當前Subject
Subject subject = SecurityUtils.getSubject();
//初始化Token信息
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
usernamePasswordToken.setRememberMe(true);
//通過令牌信息進行登錄
try {
subject.login(usernamePasswordToken);
} catch (AuthenticationException e) {
//處理登錄失敗的邏輯
logger.info("username or password is not correct");
e.printStackTrace();
}
//登錄成功
logger.info("welcome to the application!");
}
//測試
public static void main(String[] args) {
// 測試1
authenticate("joe", "123456");
// 測試2
authenticate("rose", "123456");
}
}
測試結果
測試1:
測試2:
內部流程
這部分我們來看一下在Shiro內部Authentication是如何進行的,設計組件如下圖(五個部分,下面會一一講解):
- 通過調用Subject.login(token)來觸發認證,需要傳入AuthenticationToken來獲取相關的principal和credential
- 通過第一步後,底層會進行調用securityManager的login方法
- 通過第二步後,底層securityManager會調用authenticator.authenticate(token),典型的authenticator是ModularRealmAuthenticator可以支持可拔插式配置Realm
- 通過第三步後,authenticator會通過AuthenticationStrategy來針對不同的Realm定義不同的認證策略。
- 最後會查詢配置好的realm的信息依次來進行信息匹對。
總結
本文主要講解了Shiro進行身份驗證的流程,並對底層的各個組件進行了講解。後續文章還對針對Realm部分的配置以及源碼進行分析。