Springboot整合Shiro怎麼實現登入與權限校驗
Springboot-cli 開發鷹架系列
Springboot優雅的整合Shiro進行登入校驗,權限認證(附原始碼下載)
簡介
Springboo設定Shiro進行登入校驗,權限認證,附demo演示。
前言
我們致力於讓開發者快速建立基礎環境並讓應用程式跑起來,提供使用範例供使用者參考,讓初學者快速上手。
本部落格專案原始碼位址:
專案原始碼github位址
專案原始碼國內gitee位址
1.環境
依賴
#<!-- 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:
tracking-modes: COOKIE
port: 9999
servlet:
session:
# 讓Tomcat只能從COOKIE中取得會話資訊,
# 讓Tomcat只能從COOKIE中取得會話資訊,這樣,當沒有Cookie時,URL也不會被自動加上;jsessionid=… 了。
spring:
thymeleaf:
# 關閉頁面緩存,以便於開發環境測試
cache: false
1 # 靜態資源路徑 : classpath:/templates/
# 網頁資源預設.html結尾
mode: HTML
2.簡介
Shiro三大功能模組
Subject
認證主體,通常指使用者(把操做交給SecurityManager)。
SecurityManager
安全管理器,安全管理器,管理全部Subject,能夠配合內部安全元件(關聯Realm)
Realm
網域對象,用於進行權限資訊的驗證,shiro連接資料的橋樑,如我們的登入校驗,權限校驗就在Realm進行定義。
3. Realm設定
定義使用者實體User ,可依照自己的業務自行定義
@Data @Accessors(chain = true) public class User { /** * 用户id */ private Long userId; /** * 用户名 */ private String username; /** * 密码 */ private String password; /** * 用户别称 */ private String name; }
重寫AuthorizingRealm 中登入校驗doGetAuthenticationInfo及授權doGetAuthorizInfoation方法,撰寫我們自訂的校驗邏輯。
/** * 自定义登录授权 * * @author ding */ public class UserRealm extends AuthorizingRealm { /** * 授权 * 此处权限授予 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); // 在这里为每一个用户添加vip权限 info.addStringPermission("vip"); return info; } /** * 认证 * 此处实现我们的登录逻辑,如账号密码验证 */ @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()); } /** * 此处模拟用户数据 * 实际开发中,换成数据库查询获取即可 */ private User getUser() { return new User() .setName("admin") .setUserId(1L) .setUsername("admin") .setPassword("123456"); } }
4. 核心設定
ShiroConfig.java
#/**
* Shiro內建過濾器,能夠實現攔截器相關的攔截器
* 經常使用的過濾器:
* anon:無需認證(登陸)能夠存取
* authc:必須認證才能夠存取
* user:若是使用rememberMe的功能能夠直接存取
* perms:該資源必須獲得資源權限才能夠訪問,格式perms[權限1,權限2]
* role:此資源必須取得角色權限才能夠存取
**/
/** * shiro核心管理器 * * @author ding */ @Configuration public class ShiroConfig { /** * 无需认证就可以访问 */ private final static String ANON = "anon"; /** * 必须认证了才能访问 */ private final static String AUTHC = "authc"; /** * 拥有对某个资源的权限才能访问 */ private final static String PERMS = "perms"; /** * 创建realm,这里返回我们上一把定义的UserRealm */ @Bean(name = "userRealm") public UserRealm userRealm() { return new UserRealm(); } /** * 创建安全管理器 */ @Bean(name = "securityManager") public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); //绑定realm对象 securityManager.setRealm(userRealm); return securityManager; } /** * 授权过滤器 */ @Bean public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean(); // 设置安全管理器 bean.setSecurityManager(defaultWebSecurityManager); // 添加shiro的内置过滤器 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); // 设置跳转登陆页 bean.setLoginUrl("/login"); // 无权限跳转 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) { //获取当前的用户 Subject subject = SecurityUtils.getSubject(); //用来存放错误信息 String msg = ""; //如果未认证 if (!subject.isAuthenticated()) { //将用户名和密码封装到shiro中 UsernamePasswordToken token = new UsernamePasswordToken(username, password); try { // 执行登陆方法 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.網頁資源
在resources中建立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> <h2 id="首页">首页</h2> <!-- 使用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"> <h3 id="登陆页">登陆页</h3> <h7>账号:admin,密码:123456</h7> <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> <h2 id="用户信息">用户信息</h2> <!-- 利用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> <h2 id="table">table</h2> </body> </html>
7.效果示範
啟動專案瀏覽器輸入127.0.0.1:9999
#當我們點選使用者資訊和table時會自動跳轉登入頁面
登入成功後
取得使用者資訊
這裡取得的就是我們就是我們前面doGetAuthenticationInfo方法傳回的使用者訊息,這裡為了示範就全部回傳了,實際生產中密碼是不能回傳的。
以上是Springboot整合Shiro怎麼實現登入與權限校驗的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Jasypt介紹Jasypt是一個java庫,它允許開發員以最少的努力為他/她的專案添加基本的加密功能,並且不需要對加密工作原理有深入的了解用於單向和雙向加密的高安全性、基於標準的加密技術。加密密碼,文本,數字,二進位檔案...適合整合到基於Spring的應用程式中,開放API,用於任何JCE提供者...添加如下依賴:com.github.ulisesbocchiojasypt-spring-boot-starter2. 1.1Jasypt好處保護我們的系統安全,即使程式碼洩露,也可以保證資料來源的

使用場景1、下單成功,30分鐘未支付。支付超時,自動取消訂單2、訂單簽收,簽收後7天未進行評估。訂單超時未評價,系統預設好評3、下單成功,商家5分鐘未接單,訂單取消4、配送超時,推播簡訊提醒…對於延時比較長的場景、即時性不高的場景,我們可以採用任務調度的方式定時輪詢處理。如:xxl-job今天我們採

一、Redis實現分散式鎖原理為什麼需要分散式鎖在聊分散式鎖之前,有必要先解釋一下,為什麼需要分散式鎖。與分散式鎖相對就的是單機鎖,我們在寫多執行緒程式時,避免同時操作一個共享變數產生資料問題,通常會使用一把鎖來互斥以保證共享變數的正確性,其使用範圍是在同一個進程中。如果換做是多個進程,需要同時操作一個共享資源,如何互斥?現在的業務應用通常是微服務架構,這也意味著一個應用會部署多個進程,多個進程如果需要修改MySQL中的同一行記錄,為了避免操作亂序導致髒數據,此時就需要引入分佈式鎖了。想要實現分

springboot讀取文件,打成jar包後訪問不到最新開發出現一種情況,springboot打成jar包後讀取不到文件,原因是打包之後,文件的虛擬路徑是無效的,只能通過流去讀取。文件在resources下publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

在Springboot+Mybatis-plus不使用SQL語句進行多表添加操作我所遇到的問題準備工作在測試環境下模擬思維分解一下:創建出一個帶有參數的BrandDTO對像模擬對後台傳遞參數我所遇到的問題我們都知道,在我們使用Mybatis-plus中進行多表操作是極其困難的,如果你不使用Mybatis-plus-join這一類的工具,你只能去配置對應的Mapper.xml文件,配置又臭又長的ResultMap,然後再寫對應的sql語句,這種方法雖然看上去很麻煩,但具有很高的靈活性,可以讓我們

1.自訂RedisTemplate1.1、RedisAPI預設序列化機制基於API的Redis快取實作是使用RedisTemplate範本進行資料快取操作的,這裡開啟RedisTemplate類,查看該類別的源碼資訊publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations,BeanClassLoaderAware{//聲明了value的各種序列化方式,初始值為空@NullableprivateRedisSe

SpringBoot和SpringMVC都是Java開發中常用的框架,但它們之間有一些明顯的差異。本文將探究這兩個框架的特點和用途,並對它們的差異進行比較。首先,我們來了解一下SpringBoot。 SpringBoot是由Pivotal團隊開發的,它旨在簡化基於Spring框架的應用程式的建立和部署。它提供了一種快速、輕量級的方式來建立獨立的、可執行

本文來寫個詳細的例子來說下dubbo+nacos+Spring Boot開發實戰。本文不會講述太多的理論的知識,會寫一個最簡單的例子來說明dubbo如何與nacos整合,快速建構開發環境。
