您好,登錄后才能下訂單哦!
這篇文章主要介紹“Springboot整合Shiro怎么實現(xiàn)登錄與權(quán)限校驗”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Springboot整合Shiro怎么實現(xiàn)登錄與權(quán)限校驗”文章能幫助大家解決問題。
Springboot優(yōu)雅的整合Shiro進行登錄校驗,權(quán)限認證(附源碼下載)
Springboo配置Shiro進行登錄校驗,權(quán)限認證,附demo演示。
我們致力于讓開發(fā)者快速搭建基礎(chǔ)環(huán)境并讓應(yīng)用跑起來,提供使用示例供使用者參考,讓初學者快速上手。
本博客項目源碼地址:
項目源碼github地址
項目源碼國內(nèi)gitee地址
依賴
<!-- 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中獲取會話信息,這樣,當沒有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
Shiro三大功能模塊
Subject
認證主體,通常指用戶(把操做交給SecurityManager)。
SecurityManager
安全管理器,安全管理器,管理全部Subject,能夠配合內(nèi)部安全組件(關(guān)聯(lián)Realm)
Realm
域?qū)ο?,用于進行權(quán)限信息的驗證,shiro連接數(shù)據(jù)的橋梁,如我們的登錄校驗,權(quán)限校驗就在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"); } }
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(); } }
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 { // 執(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"; } }
在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> <h2>首頁</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>登陸頁</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>用戶信息</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>table</h2> </body> </html>
啟動項目瀏覽器輸入127.0.0.1:9999
當我們點擊用戶信息和table時會自動跳轉(zhuǎn)登錄頁面
登錄成功后
獲取用戶信息
此處獲取的就是我們就是我們前面doGetAuthenticationInfo方法返回的用戶信息,這里為了演示就全部返回了,實際生產(chǎn)中密碼是不能返回的。
關(guān)于“Springboot整合Shiro怎么實現(xiàn)登錄與權(quán)限校驗”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。