Spring Boot與Shiro整合實現用戶認證

2020-12-24 黑馬程式設計師

1.1. 分析Shiro的核心API

Subject: 用戶主體(把操作交給SecurityManager)

SecurityManager:安全管理器(關聯Realm)

Realm:Shiro連接數據的橋梁

1.2. Spring Boot整合Shiro

1.2.1. 導入shiro與spring整合依賴

修改pom.xml

<!-- shiro與spring整合依賴 --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.4.0</version></dependency>

1.2.2. 自定義Realm類

package com.itheima.shiro;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;/*** 自定義Realm * @author lenovo * */public class UserRealm extends AuthorizingRealm{/** * 執行授權邏輯 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {System.out.println("執行授權邏輯");return null;}/** * 執行認證邏輯 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {System.out.println("執行認證邏輯");return null;}}

1.2.3. 編寫Shiro配置類(*)

package com.itheima.shiro;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/*** Shiro的配置類 * @author lenovo * */@Configurationpublic class ShiroConfig {/** * 創建ShiroFilterFactoryBean */ @Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//設置安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);return shiroFilterFactoryBean;}/** * 創建DefaultWebSecurityManager */@Bean(name="securityManager")public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();//關聯realmsecurityManager.setRealm(userRealm);return securityManager;}/** * 創建Realm */@Bean(name="userRealm")public UserRealm getRealm(){return new UserRealm();}}

1.3. 使用Shiro內置過濾器實現頁面攔截

package com.itheima.shiro;import java.util.LinkedHashMap;import java.util.Map;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/*** Shiro的配置類 * @author lenovo * */@Configurationpublic class ShiroConfig {/** * 創建ShiroFilterFactoryBean */@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager")DefaultWebSecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//設置安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);//添加Shiro內置過濾器/** * Shiro內置過濾器,可以實現權限相關的攔截器 * 常用的過濾器: * anon: 無需認證(登錄)可以訪問 * authc: 必須認證才可以訪問 * user: 如果使用rememberMe的功能可以直接訪問 * perms: 該資源必須得到資源權限才可以訪問 * role: 該資源必須得到角色權限才可以訪問 */Map<String,String> filterMap = new LinkedHashMap<String,String>();/*filterMap.put("/add", "authc");filterMap.put("/update", "authc");*/filterMap.put("/testThymeleaf", "anon");filterMap.put("/*", "authc");//修改調整的登錄頁面shiroFilterFactoryBean.setLoginUrl("/toLogin");shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);return shiroFilterFactoryBean;}/** * 創建DefaultWebSecurityManager */@Bean(name="securityManager")public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm")UserRealm userRealm){DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();//關聯realmsecurityManager.setRealm(userRealm);return securityManager;}/** * 創建Realm */@Bean(name="userRealm")public UserRealm getRealm(){return new UserRealm();}}

1.4. 實現用戶認證(登錄)操作

1.4.1. 設計登錄頁面

<!DOCTYPE html><html><head><meta charset="UTF-8"><title>登錄頁面</title></head><body><h3>登錄</h3><form method="post" action="login">用戶名:<input type="text" name="name"/><br/>密碼:<input type="password" name="password"/><br/><input type="submit" value="登錄"/></form></body></html>

1.4.2. 編寫Controller的登錄邏輯

/*** 登錄邏輯處理 */@RequestMapping("/login")public String login(String name,String password,Model model){/** * 使用Shiro編寫認證操作 *///1.獲取SubjectSubject subject = SecurityUtils.getSubject();//2.封裝用戶數據UsernamePasswordToken token = new UsernamePasswordToken(name,password);//3.執行登錄方法try {subject.login(token);//登錄成功//跳轉到test.htmlreturn "redirect:/testThymeleaf";} catch (UnknownAccountException e) {//e.printStackTrace();//登錄失敗:用戶名不存在model.addAttribute("msg", "用戶名不存在");return "login";}catch (IncorrectCredentialsException e) {//e.printStackTrace();//登錄失敗:密碼錯誤model.addAttribute("msg", "密碼錯誤");return "login";}}

1.4.3. 編寫Realm的判斷邏輯

package com.itheima.shiro;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;/*** 自定義Realm * @author lenovo * */public class UserRealm extends AuthorizingRealm{/** * 執行授權邏輯 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {System.out.println("執行授權邏輯");return null;}/** * 執行認證邏輯 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {System.out.println("執行認證邏輯");//假設資料庫的用戶名和密碼String name = "eric";String password = "123456";//編寫shiro判斷邏輯,判斷用戶名和密碼//1.判斷用戶名UsernamePasswordToken token = (UsernamePasswordToken)arg0;if(!token.getUsername().equals(name)){//用戶名不存在return null;//shiro底層會拋出UnKnowAccountException}//2.判斷密碼return new SimpleAuthenticationInfo("",password,"");}}

1.5. 整合MyBatis實現登錄

1.5.1. 導入mybatis相關的依賴

<!-- 導入mybatis相關的依賴 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.9</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- SpringBoot的Mybatis啟動器 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.1.1</version></dependency>

1.5.2. 配置application.properties

位置:src/main/resources目錄下

spring.datasource.driverClassName=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=rootspring.datasource.type=com.alibaba.druid.pool.DruidDataSourcemybatis.type-aliases-package=com.itheima.domain

1.5.3. 編寫User實體

package com.itheima.domain;public class User {private Integer id;private String name;private String password;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

1.5.4. 編寫UserMapper接口

package com.itheima.mapper;import com.itheima.domain.User;public interface UserMapper {public User findByName(String name);}

1.5.5. 編寫UserMapper.xml映射文件

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 該文件存放CRUD的sql語句 --><mapper namespace="com.itheima.mapper.UserMapper"><select id="findByName" parameterType="string" resultType="user">SELECT id,NAME,PASSWORDFROMuser where name = #{value}</select></mapper>

1.5.6. 編寫業務接口和實現

接口:

package com.itheima.service;import com.itheima.domain.User;public interface UserService {public User findByName(String name);}

實現;

package com.itheima.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.itheima.domain.User;import com.itheima.mapper.UserMapper;import com.itheima.service.UserService;@Servicepublic class UserServiceImpl implements UserService{//注入Mapper接口@Autowiredprivate UserMapper userMapper;@Overridepublic User findByName(String name) {return userMapper.findByName(name);}}

1.5.7. 添加@MapperScan註解

package com.itheima;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/*** SpringBoot啟動類 * @author lenovo * */@SpringBootApplication@MapperScan("com.itheima.mapper")public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

1.5.8. 修改UserRealm

package com.itheima.shiro;import org.apache.shiro.authc.AuthenticationException;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.SimpleAuthenticationInfo;import org.apache.shiro.authc.UsernamePasswordToken;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import com.itheima.domain.User;import com.itheima.service.UserService;/*** 自定義Realm * @author lenovo * */public class UserRealm extends AuthorizingRealm{/** * 執行授權邏輯 */@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {System.out.println("執行授權邏輯");return null;}@Autowiredprivate UserService userSerivce;/** * 執行認證邏輯 */@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {System.out.println("執行認證邏輯");//編寫shiro判斷邏輯,判斷用戶名和密碼//1.判斷用戶名UsernamePasswordToken token = (UsernamePasswordToken)arg0;User user = userSerivce.findByName(token.getUsername());if(user==null){//用戶名不存在return null;//shiro底層會拋出UnKnowAccountException}//2.判斷密碼return new SimpleAuthenticationInfo("",user.getPassword(),"");}}

相關焦點

  • spring boot 整合shiro 錯誤
    最近在弄spring boot 整合shiro的。凱哥現在用的是spring boot。web.xml沒有。但是凱哥配置了shiro的核心攔截器啊。如下圖:並且使用了@Configuration這個註解了。
  • Spring Boot 整合 Shiro,兩種方式全總結
    ><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency
  • javaEE開發必用的技術 ssm框架+shiro框架實現權限控制及認證
    本文將使用spring,springmvc,mybatis,shiro都是最新版本的框架+JDK1.8完成用戶登錄模塊的DEMO,該DEMO具備較完善的功能,大部分項目都要做權限控制,大部分項目的思路都可以用來參照。
  • Spring Shiro 學習系統 Spring-Shiro-training
    Spring-Shiro-training 詳細介紹Spring Shiro 學習系統簡介基於 springmvc、spring、mybatis-plus、shiro技術和功能Spring-cache、Spring-data-redis、Spring-Task、Shiro、Spring-cache-shiro、maven profile 多環境配置權限管理、角色管理、用戶管理、部門管理、登陸日誌、圖標管理
  • web應用安全框架選型:Spring Security與Apache Shiro
    web應用安全框架選型:Spring Security與Apache Shiro一、 SpringSecurity 框架簡介Spring Security 是強大的,且容易定製的,基於Spring開發的實現認證登錄與資源授權的應用安全框架。
  • Spring Boot 2.4 安裝
    一個需要注意的是,你的項目如果需要轉換為 Spring Boot 的項目的話,你的項目必須是 spring-boot-starter-parent的子項目。安裝 Spring BootSpring Boot 可以通過使用 「傳統(classic)」 的 Java 開發工具或者安裝一個命令行工具(command line tool)。
  • oauth2-shiro 0.1-beta 發布
    經過不斷地試錯與研究, 整合oauth2與shiro的 oauth2-shiro項目 0.1-beta 發布. 整合Apache Oltu 與 Shiro.
  • Spring Boot Admin快速打造監控平臺
    今天我們介紹一個可視化的監控指標平臺Spring Boot Admin,它利用spring-boot-starter-actuator提供的功能,將各個微服務的狀態整合到一起,並提供良好的界面查看支持,並且能夠動態的修改實例日誌級別
  • web開發實戰教程:Apache Shiro在web項目的應用
    shiro安全框架是目前為止作為登錄註冊最常用的框架,因為它十分的強大簡單,提供了認證、授權、加密和會話管理等功能 。shiro能做什麼?認證:驗證用戶的身份授權:對用戶執行訪問控制:判斷用戶是否被允許做某事會話管理:在任何環境下使用 Session API,即使沒有 Web 或EJB 容器。
  • Spring boot 2.1.8 中 @SpringBootApplication 註解來源
    簡介啟動Spring boot 時,啟動類中有個註解 @SpringBootApplication查看源碼其中標註的三個註解正能解決我們上面所說的三種功能其實有個問題需要說明下,@SpringBootAplication 中 @ComponentScan 並不是默認值,而是排除了TypeFilter的實現:TypeExcludeFilter和AutoConfigurationExcludeFilter 這點與官網的文檔描述有些差異。
  • Spring Boot 啟動事件和監聽器,太強大了!
    Spring Boot 基礎的構建這裡就不介紹了,如果你對 Spring Boot 還不是很熟悉,或者只是會簡單的使用,那還是建議你深入學習下吧,推薦這個 Spring Boot 學習倉庫,歡迎 Star 關注:https://github.com/javastacks/spring-boot-best-practice1、新建監聽器
  • 反爬蟲防盜刷 Spring Boot 組件 kk-anti-reptile 初版發布
    kk-anti-reptile 是適用於基於spring-boot開發的分布式系統的反爬蟲組件系統要求 基於spring-boot開發(spring-boot1
  • 如何在Spring Boot項目中集成微信支付V3
    Payment Spring Boot是微信支付V3的Java實現,僅僅依賴Spring內置的一些類庫。配置簡單方便,可以讓開發者快速為Spring Boot應用接入微信支付。演示例子: payment-spring-boot-samples文檔:Payment Spring Boot文檔有疑問請提交ISSUE會及時跟進,歡迎Star ,歡迎PR貢獻。
  • Spring Boot集成validation用於優雅的校驗API參數的合法性
    validation主要是校驗用戶提交的數據的合法性,比如是否為空,密碼是否符合規則,郵箱格式是否正確等等,校驗框架比較多,用的比較多的是hibernate-validator, 也支持國際化,也可以自定義校驗類型的註解,這裡只是簡單的演示校驗框架在Spring Boot中的簡單集成
  • Shiro 權限校驗分析
    Authorization:授權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限; 即判斷用戶是否能做事情,常見的如:驗證某個用戶是否擁有某個角色。或者細粒度的驗證某個用戶對某個資源是否具有某個權限。
  • Rocket-API 2.3.2 發布,基於 spring boot 的 API 敏捷開發框架
    通過約定的方式 實現統一的標準。告別加班,拒絕重複勞動,遠離搬磚概述"Rocket-API" 基於spring boot 的API敏捷開發框架,服務端50%以上的功能只需要寫SQL或者 mongodb原始執行腳本就能完成開發,另外30%也在不停的完善公共組件,比如文件上傳,下載,導出,預覽,分頁等等通過一二行代碼也能完成開發,剩下的20%也能依賴於動態編譯技術生成class的形式,不需要發布部署,不需要重啟來實現研發團隊的快速編碼
  • 老的SpringMVC項目接入shiro步驟
    現在想接入shiro把權限這塊管理起來。關於shiro網上的資料已經很多了,我就不重複了。直接開搞。先要在web.xml中配置shiro過濾器,接管所有請求。<!-- 使用shiro認證 --><!
  • Spring Boot 2.4 從早期版本進行升級
    如果你希望啟用上面的這個特性的話,請將下面的依賴添加到你的項目中:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-properties-migrator</artifactId>
  • 使用IntelliJ IDEA創建Spring Boot項目
    1.2 填寫項目信息在此步驟中,需要指定一些必要的項目信息,它們是:Group:項目的groupId,例如com.ramostearArtifact:項目的artifactId,例如hello-springbootType:項目的構建方式,默認為