Springboot整合Shiro實現(xiàn)登錄與權(quán)限校驗詳細解讀
Springboot-cli 開發(fā)腳手架系列
Springboot優(yōu)雅的整合Shiro進行登錄校驗,權(quán)限認證(附源碼下載)
簡介
Springboo配置Shiro進行登錄校驗,權(quán)限認證,附demo演示。
前言
我們致力于讓開發(fā)者快速搭建基礎(chǔ)環(huán)境并讓應(yīng)用跑起來,提供使用示例供使用者參考,讓初學(xué)者快速上手。
本博客項目源碼地址:
1. 環(huán)境
依賴
<!-- Shiro核心框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.9.0</version>
</dependency>
<!-- Shiro使用Spring框架 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.9.0</version>
</dependency>
<!-- Thymeleaf中使用Shiro標簽 -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
yml配置
server:
port: 9999
servlet:
session:
# 讓Tomcat只能從COOKIE中獲取會話信息,這樣,當(dāng)沒有Cookie時,URL也就不會被自動添加上 ;jsessionid=… 了。
tracking-modes: COOKIEspring:
thymeleaf:
# 關(guān)閉頁面緩存,便于開發(fā)環(huán)境測試
cache: false
# 靜態(tài)資源路徑
prefix: classpath:/templates/
# 網(wǎng)頁資源默認.html結(jié)尾
mode: HTML
2. 簡介
Shiro三大功能模塊
- Subject
認證主體,通常指用戶(把操做交給SecurityManager)。
- SecurityManager
安全管理器,安全管理器,管理全部Subject,能夠配合內(nèi)部安全組件(關(guān)聯(lián)Realm)
- Realm
域?qū)ο?,用于進行權(quán)限信息的驗證,shiro連接數(shù)據(jù)的橋梁,如我們的登錄校驗,權(quán)限校驗就在Realm進行定義。
3. Realm配置
定義用戶實體User ,可根據(jù)自己的業(yè)務(wù)自行定義
@Data
@Accessors(chain = true)
public class User {
/**
* 用戶id
*/
private Long userId;
/**
* 用戶名
*/
private String username;
/**
* 密碼
*/
private String password;
/**
* 用戶別稱
*/
private String name;
}重寫AuthorizingRealm 中登錄校驗doGetAuthenticationInfo及授權(quán)doGetAuthorizationInfo方法,編寫我們自定義的校驗邏輯。
/**
* 自定義登錄授權(quán)
*
* @author ding
*/
public class UserRealm extends AuthorizingRealm {
/**
* 授權(quán)
* 此處權(quán)限授予
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 在這里為每一個用戶添加vip權(quán)限
info.addStringPermission("vip");
return info;
}
/**
* 認證
* 此處實現(xiàn)我們的登錄邏輯,如賬號密碼驗證
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 獲取到token
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
// 從token中獲取到用戶名和密碼
String username = token.getUsername();
String password = String.valueOf(token.getPassword());
// 為了方便,這里模擬獲取用戶
User user = this.getUser();
if (!user.getUsername().equals(username)) {
throw new UnknownAccountException("用戶不存在");
} else if (!user.getPassword().equals(password)) {
throw new IncorrectCredentialsException("密碼錯誤");
}
// 校驗完成后,此處我們把用戶信息返回,便于后面我們通過Subject獲取用戶的登錄信息
return new SimpleAuthenticationInfo(user, password, getName());
}
/**
* 此處模擬用戶數(shù)據(jù)
* 實際開發(fā)中,換成數(shù)據(jù)庫查詢獲取即可
*/
private User getUser() {
return new User()
.setName("admin")
.setUserId(1L)
.setUsername("admin")
.setPassword("123456");
}
}4. 核心配置
ShiroConfig.java
/**
* Shiro內(nèi)置過濾器,能夠?qū)崿F(xiàn)攔截器相關(guān)的攔截器
* 經(jīng)常使用的過濾器:
* anon:無需認證(登陸)能夠訪問
* authc:必須認證才能夠訪問
* user:若是使用rememberMe的功能能夠直接訪問
* perms:該資源必須獲得資源權(quán)限才能夠訪問,格式 perms[權(quán)限1,權(quán)限2]
* role:該資源必須獲得角色權(quán)限才能夠訪問
**/
/**
* shiro核心管理器
*
* @author ding
*/
@Configuration
public class ShiroConfig {
/**
* 無需認證就可以訪問
*/
private final static String ANON = "anon";
/**
* 必須認證了才能訪問
*/
private final static String AUTHC = "authc";
/**
* 擁有對某個資源的權(quán)限才能訪問
*/
private final static String PERMS = "perms";
/**
* 創(chuàng)建realm,這里返回我們上一把定義的UserRealm
*/
@Bean(name = "userRealm")
public UserRealm userRealm() {
return new UserRealm();
}
/**
* 創(chuàng)建安全管理器
*/
@Bean(name = "securityManager")
public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//綁定realm對象
securityManager.setRealm(userRealm);
return securityManager;
}
/**
* 授權(quán)過濾器
*/
@Bean
public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
// 設(shè)置安全管理器
bean.setSecurityManager(defaultWebSecurityManager);
// 添加shiro的內(nèi)置過濾器
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/index", ANON);
filterMap.put("/userInfo", PERMS + "[vip]");
filterMap.put("/table2", AUTHC);
filterMap.put("/table3", PERMS + "[vip2]");
bean.setFilterChainDefinitionMap(filterMap);
// 設(shè)置跳轉(zhuǎn)登陸頁
bean.setLoginUrl("/login");
// 無權(quán)限跳轉(zhuǎn)
bean.setUnauthorizedUrl("/unAuth");
return bean;
}
/**
* Thymeleaf中使用Shiro標簽
*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
}5. 接口編寫
IndexController.java
/**
* @author ding
*/
@Controller
public class IndexController {
@RequestMapping({"/", "/index"})
public String index(Model model) {
model.addAttribute("msg", "hello,shiro");
return "/index";
}
@RequestMapping("/userInfo")
public String table1(Model model) {
return "userInfo";
}
@RequestMapping("/table")
public String table(Model model) {
return "table";
}
@GetMapping("/login")
public String login() {
return "login";
}
@PostMapping(value = "/doLogin")
public String doLogin(@RequestParam("username") String username, @RequestParam("password") String password, Model model) {
//獲取當(dāng)前的用戶
Subject subject = SecurityUtils.getSubject();
//用來存放錯誤信息
String msg = "";
//如果未認證
if (!subject.isAuthenticated()) {
//將用戶名和密碼封裝到shiro中
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
// 執(zhí)行登陸方法
subject.login(token);
} catch (Exception e) {
e.printStackTrace();
msg = "賬號或密碼錯誤";
}
//如果msg為空,說明沒有異常,就返回到主頁
if (msg.isEmpty()) {
return "redirect:/index";
} else {
model.addAttribute("errorMsg", msg);
return "login";
}
}
return "/login";
}
@GetMapping("/logout")
public String logout() {
SecurityUtils.getSubject().logout();
return "index";
}
@GetMapping("/unAuth")
public String unAuth() {
return "unAuth";
}
}6. 網(wǎng)頁資源
在resources中創(chuàng)建templates文件夾存放頁面資源
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<html xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首頁</h1>
<!-- 使用shiro標簽 -->
<shiro:authenticated>
<p>用戶已登錄</p> <a th:href="@{/logout}" rel="external nofollow" >退出登錄</a>
</shiro:authenticated>
<shiro:notAuthenticated>
<p>用戶未登錄</p>
</shiro:notAuthenticated>
<br/>
<a th:href="@{/userInfo}" rel="external nofollow" >用戶信息</a>
<a th:href="@{/table}" rel="external nofollow" >table</a>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登陸頁</title>
</head>
<body>
<div>
<p th:text="${errorMsg}"></p>
<form action="/doLogin" method="post">
<h2>登陸頁</h2>
<h6>賬號:admin,密碼:123456</h6>
<input type="text" id="username" name="username" placeholder="admin">
<input type="password" id="password" name="password" placeholder="123456">
<button type="submit">登陸</button>
</form>
</div>
</body>
</html>
userInfo.html
<!DOCTYPE html>
<html lang="en" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
<meta charset="UTF-8">
<title>table1</title>
</head>
<body>
<h1>用戶信息</h1>
<!-- 利用shiro獲取用戶信息 -->
用戶名:<shiro:principal property="username"/>
<br/>
用戶完整信息: <shiro:principal/>
</body>
</html>
table.hetml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>table</title>
</head>
<body>
<h1>table</h1>
</body>
</html>
7. 效果演示
啟動項目瀏覽器輸入127.0.0.1:9999

當(dāng)我們點擊用戶信息和table時會自動跳轉(zhuǎn)登錄頁面

登錄成功后

獲取用戶信息
此處獲取的就是我們就是我們前面doGetAuthenticationInfo方法返回的用戶信息,這里為了演示就全部返回了,實際生產(chǎn)中密碼是不能返回的。

8. 源碼分享
本項目已收錄
Springboot-cli開發(fā)腳手架,集合各種常用框架使用案例,完善的文檔,致力于讓開發(fā)者快速搭建基礎(chǔ)環(huán)境并讓應(yīng)用跑起來,并提供豐富的使用示例供使用者參考,幫助初學(xué)者快速上手。
到此這篇關(guān)于Springboot整合Shiro實現(xiàn)登錄與權(quán)限校驗詳細分解的文章就介紹到這了,更多相關(guān)Springboot Shiro登陸校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot 參數(shù)校驗的具體實現(xiàn)方式
這篇文章主要介紹了Spring Boot 參數(shù)校驗的具體實現(xiàn)方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-06-06
SpringMVC如何獲取多種類型數(shù)據(jù)響應(yīng)
這篇文章主要介紹了SpringMVC如何獲取多種類型數(shù)據(jù)響應(yīng),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11
詳解Java中多線程異常捕獲Runnable的實現(xiàn)
這篇文章主要介紹了詳解Java中多線程異常捕獲Runnable的實現(xiàn)的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這樣的知識,需要的朋友可以參考下2017-10-10
spring?boot實現(xiàn)圖片上傳到后臺的功能(瀏覽器可直接訪問)
這篇文章主要介紹了spring?boot實現(xiàn)圖片上傳到后臺的功能(瀏覽器可直接訪問),需要的朋友可以參考下2022-04-04
Spring常用注解 使用注解來構(gòu)造IoC容器的方法
下面小編就為大家分享一篇Spring常用注解 使用注解來構(gòu)造IoC容器的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01

