
前言
上一篇SpringBoot:集成Shiro之簡(jiǎn)述篇中,我們簡(jiǎn)述了Shiro的基本概念以及Shiro的內(nèi)部流程方式.下面我先簡(jiǎn)述一下本篇博客的基本內(nèi)容以及使用場(chǎng)景.
本篇博客主要是講 在SpringBoot 2.0 中集成Shiro,使用INI文件的形式完成登錄認(rèn)證(只認(rèn)證非授權(quán)),使用場(chǎng)景只應(yīng)對(duì)較少的用戶的系統(tǒng),而且賬號(hào)密碼為固定.
集成環(huán)境 : Mac ? | ? JDK 1.8 ? | ? SpringBoot 2.0
?????? INI文件優(yōu)缺點(diǎn)必看,因?yàn)檫@是你架構(gòu)程序的第一步!
INI文件優(yōu)勢(shì) : 簡(jiǎn)單易懂 , 集成方便.
INI文件缺點(diǎn) : 采用硬編碼方式把認(rèn)證授權(quán)信息寫在INI文件中,可維護(hù)性差.
搭建Shiro基本環(huán)境
首先,我們先使用IDEA創(chuàng)建一個(gè)SpringBoot 2.0的web工程(關(guān)于JDK,這里我就不多說了).具體過程如下所示.
- 選擇SpringBoot模板,創(chuàng)建Spring Boot ,點(diǎn)擊下一步.

- 設(shè)定Spring Boot工程的基本配置信息.點(diǎn)擊下一步.

- 選擇Spring Boot 的所含模塊,因?yàn)檫@里我們只需要做演示功能,所以我們只選擇Web模塊,當(dāng)然了,實(shí)際工程我們需要根據(jù)我們的需求來選擇我們所需要的模塊.點(diǎn)擊下一步完成工程的創(chuàng)建.

- 然后打開工程,等待一段時(shí)間,因?yàn)槟闶褂昧薟eb模塊,所以Maven需要下載依賴的Jar包.同時(shí),我們需要導(dǎo)入Shiro的依賴Jar包,因?yàn)镾pring Boot已經(jīng)對(duì)Shiro進(jìn)行了支持.所以我們直接導(dǎo)入下面的一個(gè)依賴模塊即可.
<!-- shiro用戶權(quán)限管理 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
配置INI文件認(rèn)證部分
當(dāng)工程所有都配置完成之后,我們運(yùn)行Shiro項(xiàng)目,發(fā)現(xiàn)并不能運(yùn)行成功,報(bào)錯(cuò)信息如下所示.
***************************
APPLICATION FAILED TO START
***************************
Description:
No bean of type 'org.apache.shiro.realm.Realm' found.
Action:
Please create bean of type 'Realm' or add a shiro.ini in the root classpath (src/main/resources/shiro.ini) or in the META-INF folder (src/main/resources/META-INF/shiro.ini).
這是因?yàn)槲覀儧]有配置INI文件,所以我們根據(jù)提示在resources或者src/main/resources/META-INF文件夾下創(chuàng)建一個(gè)名為shiro.ini的文件.并且添加我們的用戶驗(yàn)證信息.如下圖所示.

然后,我們把下面的用戶信息寫入shiro.ini文件中.其中用戶root密碼為123456,用戶admin的密碼為admin.
[users]
root=123456
admin=admin
認(rèn)證邏輯代碼
下面的一張圖是上一篇博客中講述的,上一個(gè)模塊的INI文件就是對(duì)應(yīng)圖中的Realm.現(xiàn)在我們所需要做的工作內(nèi)容就是組裝Subject主體,以及配置Secruity Manager.

為了保證代碼的邏輯性,我們把驗(yàn)證邏輯抽到一個(gè)類中.然后我們開始根據(jù)INI文件創(chuàng)建SecurityManager并且綁定到SecurityUtils中,整體代碼如下所示.
//初始化SecurityManager對(duì)象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//通過SecurityManager工廠對(duì)象,獲取SecurityManager實(shí)例對(duì)象.
SecurityManager securityManager = factory.getInstance();
// 把 securityManager 實(shí)例 綁定到 SecurityUtils
SecurityUtils.setSecurityManager(securityManager);
緊接著,我們開始獲取我們Subject主體,以及配置我們的用戶信息token令牌,如下所示.
//組建Subject主體.
Subject subject = SecurityUtils.getSubject();
//創(chuàng)建 token 令牌
UsernamePasswordToken token = new UsernamePasswordToken(userName,passWord);
接下來我們就需要進(jìn)行token令牌認(rèn)證了,這里我需要說明一下,用戶登錄不成功有兩種情況,一為用戶不存在,二為用戶密碼不正確.所以我們要crash出對(duì)應(yīng)的錯(cuò)誤,然后通過不同的錯(cuò)誤類型,進(jìn)行數(shù)據(jù)的返回.這里我就統(tǒng)一用一種錯(cuò)誤表示了.不做細(xì)分處理了.具體代碼如下所示.
//用戶登錄操作.
try{
subject.login(token);
resultMap.put("code","200");
resultMap.put("msg","用戶登錄成功");
}catch (AuthenticationException e){
//登錄失敗原因 1 用戶不存在 2 用戶密碼不正確
e.printStackTrace();
resultMap.put("code","-1");
resultMap.put("msg","用戶登錄失敗");
}
上面就完成了 構(gòu)建Secruity Manager對(duì)象 、組建Subject主體、通過Realm完成認(rèn)證過程 三個(gè)步驟.接下來我們需要封裝一下,所以MyShiro整體代碼如下所示.
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class MyShiro {
public Map<String,Object> userLoginAction (String userName,String passWord){
Map<String,Object> resultMap = new HashMap<>();
//初始化SecurityManager對(duì)象
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//通過SecurityManager工廠對(duì)象,獲取SecurityManager實(shí)例對(duì)象.
SecurityManager securityManager = factory.getInstance();
// 把 securityManager 實(shí)例 綁定到 SecurityUtils
SecurityUtils.setSecurityManager(securityManager);
//組建Subject主體.
Subject subject = SecurityUtils.getSubject();
//創(chuàng)建 token 令牌
UsernamePasswordToken token = new UsernamePasswordToken(userName,passWord);
//用戶登錄操作.
try{
subject.login(token);
resultMap.put("code","200");
resultMap.put("msg","用戶登錄成功");
}catch (AuthenticationException e){
//登錄失敗原因 1 用戶不存在 2 用戶密碼不正確
resultMap.put("code","-1");
resultMap.put("msg","用戶登錄失敗");
}
return resultMap;
}
}
添加 @Component 的原因是為了方便在下一模塊使用自動(dòng)化創(chuàng)建.
用戶登錄接口
上面我們已經(jīng)完成了認(rèn)證流程的封裝,然后接下來,我們寫一個(gè)簡(jiǎn)單的用戶登錄接口,驗(yàn)證我們的shiro是否能夠正常的使用.
首先創(chuàng)建一個(gè)用戶登錄接口控制器UserLoginController,導(dǎo)入MyShiro.并且創(chuàng)建一個(gè)用戶登錄接口方法.代碼過于簡(jiǎn)單,這里就不過敘述了 ,整體代碼如下所示.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class UserLoginController {
@Autowired
MyShiro myShiro;
@RequestMapping(value = "/login",method = RequestMethod.POST)
public Map<String,Object> userLoginAction (@RequestParam(value = "userName") String userName,
@RequestParam(value = "password") String password){
Map<String,Object> resultMap = myShiro.userLoginAction(userName,password);
return resultMap;
}
}
接下來我們就運(yùn)行我們的項(xiàng)目,然后查看我們用戶是否能夠登錄成功.


結(jié)語
到這里,SpringBoot2.0集成Shiro之INI認(rèn)證篇就完結(jié)了,使用INI文件做用戶認(rèn)證操作還是很簡(jiǎn)單的.下一篇,我們將看一下,如何使用INI文件進(jìn)行授權(quán)操作,歡迎繼續(xù)關(guān)注,如果有任何問題,歡迎一切和騷棟探討~感謝大家.
Demo傳送門
