SpringBoot集成Shiro(一)驗證用戶登錄驗證
SpringBoot集成Shiro(二)驗證用戶角色
SpringBoot集成Shiro(三)驗證用戶權限
SpringBoot集成Shiro(四)驗證用戶角色升級版
學習這篇文章之前,需要對 shiro 有一個簡單的瞭解。
在SpringBoot中集成Shiro安全認證框架也很簡單,大概可以分爲以下幾步:
- 創建項目並添加依賴
- 增加登錄方法
- 增加驗證方法
- 配置Shiro
創建項目
首先在 https://start.spring.io/ 創建一個SpringBoot項目,在創建的時候把 Spring Web 依賴加上:
創建完成後打開項目,增加shiro的依賴:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
增加登錄接口
我們創建一個 UserController 來實現登錄業務
@RestController
@RequestMapping("user")
public class UserController {
@RequestMapping("login")
public String Login(String username, String password){
System.out.println("開始登錄 username:" + username +", password:" + password);
return "Login successful";
}
}
完成這一步之後,其實我們的項目已經可以跑起來了,我們運行項目,然後在瀏覽器輸入:localhost:8080/user/login 就能訪問到我們這個方法了。我們試一下:
在控制檯應該能夠看到我們的打印:
開始登錄 username:null, password:null
在瀏覽器應該能看到返回值的字符串:
Login successful
接下來我們將改造這個 login 方法,用 shiro 的方式來實現登錄:
@RequestMapping("login")
public String Login(String username, String password){
System.out.println("開始登錄 username:" + username +", password:" + password);
// 獲取 Subject
Subject subject = SecurityUtils.getSubject();
// 根據用戶名和密碼創建 Token
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try{
// 通過 subject 去登錄
subject.login(token);
}catch (UnknownAccountException e){
System.out.println("賬號不存在");
return "Login failed";
}catch (IncorrectCredentialsException e){
System.out.println("密碼不正確");
return "Login failed";
}catch (Exception e){
e.printStackTrace();
}
return "Login successful";
}
改造之後發生了一些變化,首先,我們使用 SecurityUtils 工具類創建一個 Subject,然後使用用戶名密碼創建了一個 UsernamePasswordToken。最後我們將 Token 傳入 Subject的 login 方法中去進行登錄。在最後的最後,我還捕獲了幾個異常,身份驗證失敗的時候一定記得捕獲 AuthenticationException 或其子類,常見的如:
接下來我們再來實現用戶名和密碼的驗證功能
用戶驗證
我們需要創建一個類,然後繼承 AuthorizingRealm,並實現它的兩個方法:一個是授權方法,一個是認證方法
public class UserRealm extends AuthorizingRealm {
// 這是驗證用戶權限使用的方法,暫時先不管。
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 認證方法
*
* 執行 subject.login() 方法時 就會調用本方法進行認證
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("進入身份認證器......");
// 用戶名密碼(這兩個數據應該從數據庫查詢出來)
String DB_Username="admin";
String DB_Password="123456";
//交給AuthenticatingRealm使用CredentialsMatcher進行密碼匹配,如果覺得人家的不好可以自定義實現
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
DB_Username, //用戶名
DB_Password, //密碼
ByteSource.Util.bytes(DB_Password.getBytes()),
getName() //realm name
);
return authenticationInfo;
}
}
在 doGetAuthenticationInfo 認證方法中,我將用戶名和密碼寫死了,真實項目中,這個數據應該是從數據庫查詢出來的。通過 token.getPrincipal();就可以獲取到 token 中的用戶名了,然後根據用戶名去數據庫查詢User數據就好了。
用戶驗證的邏輯已經完成了,接下來進入最後的步驟,配置!!
配置Shiro
我們使用 JavaConfig 的方式來配置:
@Configuration
public class ShiroConfig {
/**
* 第三步
* 註冊 ShiroFilterFactoryBean
* @return ShiroFilterFactoryBean
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
// 創建 ShiroFilterFactoryBean
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 將SecurityManager實例 並綁定給 ShiroFilterFactoryBean
shiroFilterFactoryBean.setSecurityManager(securityManager);
return shiroFilterFactoryBean;
}
/**
* 第一步
* 註冊UserRealm
* @return UserRealm
*/
@Bean
public UserRealm userRealm(){
return new UserRealm();
}
/**
* 第二步
* 註冊SecurityManager
* @return SecurityManager
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(userRealm());
return securityManager;
}
}
根據引用順序,我將上面三個 bean 分爲了三步。
接下來進行測試,在發送一個請求試一試:
可以看到登錄驗證成功了。
這是 SpringBoot 集成 Shiro 最簡單的配置,後續其他的安全操作都可以在這個基礎上擴展。下篇文章我們學習:如何控制用戶角色。
技 術 無 他, 唯 有 熟 爾。
知 其 然, 也 知 其 所 以 然。
踏 實 一 些, 不 要 着 急, 你 想 要 的 歲 月 都 會 給 你。