<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SpringBoot3.5.4 整合Shiro時 運行失敗,檢查思路及最終解決方案

      1. 創建過程

      1. 新建一個Shiro,去github上查看simple,需要用到哪些內容;
      2. 根據顯示的內容,在創建項目的時候導入SpringWeb,Thymeleaf
      3. 檢查pom.xml,確定導入的內容是最新的自己想要的SpringBoot3.5.4 的最新版。
      4. 在themleaf創建個首頁,編寫一個controller,測試springboot項目正常啟動
      5. 使用的Springboot3.x,所以在github的Shiro倉庫中參照:https://github.com/apache/shiro/tree/main/samples/spring-boot-3-web
      6. 引入git的pom.xml的依賴
              <dependency>
                  <groupId>org.apache.shiro</groupId>
                  <artifactId>shiro-core</artifactId>
                  <version>2.0.0-alpha-4</version>
                  <classifier>jakarta</classifier>
              </dependency>
              <dependency>
                  <groupId>org.apache.shiro</groupId>
                  <artifactId>shiro-web</artifactId>
                  <version>2.0.0-alpha-4</version>
                  <classifier>jakarta</classifier>
              </dependency>
              
              <dependency>
                  <groupId>org.apache.shiro</groupId>
                  <artifactId>shiro-spring-boot-web-starter</artifactId>
                  <version>2.0.0-alpha-4</version>
                  <classifier>jakarta</classifier>
              </dependency>
              <dependency>
                  <groupId>org.apache.shiro</groupId>
                  <artifactId>shiro-spring-boot-starter</artifactId>
                  <version>2.0.0-alpha-4</version>
                  <classifier>jakarta</classifier>
              </dependency>
              <dependency>
                  <groupId>org.apache.shiro</groupId>
                  <artifactId>shiro-spring</artifactId>
                  <version>2.0.0-alpha-4</version>
                  <classifier>jakarta</classifier>
              </dependency>
      
      1. 編寫Configuration 參照samples/spring-boot-3-web/src/main/java/org/apache/shiro/samples/WebApp.java
      package com.demo.config;
      
      import org.apache.shiro.mgt.DefaultSecurityManager;
      import org.apache.shiro.realm.Realm;
      import org.apache.shiro.realm.text.TextConfigurationRealm;
      import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
      import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
      import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      /**
       * Apache Shiro 核心配置類
       * 用于集成 Shiro 權限框架到 Spring Boot 3.x 應用
       */
      @Configuration
      public class ShiroConfig {
      
          /**
           * 創建并配置Realm Bean用于權限管理
           *
           * @return 配置好的TextConfigurationRealm實例
           */
          @Bean
          public Realm realm() {
              TextConfigurationRealm realm = new TextConfigurationRealm();
      
              // 配置用戶及其對應的權限角色
              // 配置用戶:格式為 username = password, role1, role2, ...
              realm.setUserDefinitions(
                      "admin=admin,admin,manager,user\n"
                              + "manager=manager,manager,user\n"
                              + "user=user,user");
      
              // 配置角色及其關系 這里不是“角色繼承”,而是“角色擁有的權限”
              // 配置角色權限(可選):格式為 role = permission1, permission2, ...
              realm.setRoleDefinitions(
                        "admin=*:*:*\n"
                      + "manager=read:write\n"
                      + "user=read"
              );
      
              return realm;
          }
      
          /**
           * 配置 Shiro 過濾器鏈
           * 定義哪些路徑需要什么樣的過濾器(權限控制)
           *
           * @return ShiroFilterChainDefinition 實例
           */
          @Bean
          public ShiroFilterChainDefinition shiroFilterChainDefinition() {
              DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
      
              // /login 路徑允許匿名訪問(anon),即未登錄用戶也可以訪問,用于登錄頁面或登錄接口。
              chainDefinition.addPathDefinition("/login", "anon");
              // 訪問 /logout 需要登出(logout),即用戶可登出。
              chainDefinition.addPathDefinition("/logout", "logout");
      
              // 訪問根路徑 / 需要認證(authc),即用戶必須已登錄才可訪問。
              chainDefinition.addPathDefinition("/**", "authc");
      
              return chainDefinition;
          }
      
          /**
           * 【關鍵】配置 SecurityManager
           * 這是 Shiro 的核心,必須顯式聲明為 Bean
           * shiro-spring-boot-starter 會自動使用這個 Bean
           *
           * @param realm 從 Spring 容器注入的 Realm
           * @return 配置好的 SecurityManager
           */
          @Bean
          public DefaultWebSecurityManager  securityManager(Realm realm) {
              DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager ();
              securityManager.setRealm(realm);
              return securityManager;
          }
      
      }
      
      

      問題點

      • 期間一直報錯java.lang.IllegalStateException,ClassNotFoundException,多方查找資料后發現是因為 Shiro 和 Spring Boot 版本不兼容導致的。是一個典型的 Jakarta EE 9+ 遷移問題,其中 javax.servlet 包被重命名為 jakarta.servlet

      解決方案直接看最后,中間都是找問題和解決問題的過程

      思路及解決方案

      網絡上提出的解決方案有下面幾種
      1. 降級 Spring Boot 版本,降到SpringBoot 2.x 使用javax.servlet的那個版本,因為本身想根據視頻中的思路,學習最新的知識。故而pass;
      2. 升級 Shiro 版本,目前所使用的版本就是直接從github上查找所取下來的最新版的master版本,2.0.0-alpha-4,所以不存在不是最新的版的情況,先放一邊;
      3. 添加 Jakarta Servlet API 兼容性依賴,添加一個橋接的依賴包,使Javax和Jakarta整合,合理;

      使用上述方式意義嘗試后,依舊提示有問題,又去通義上讓AI給寫一個Shiro的整合方案,檢查后發現少注入的一個SecurityManager,

      image
      因為SecurityManager是已經被廢止的對象,原本想使用上級對象,但是發現其實返回的也是 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager ();,所以使用了DefaultWebSecurityManager 補充后重新測試,程序能正常加載

      image

      附加

      碎碎念

      思緒很多,找了各方資料,就是不行,原因就是Spring6已經遷移了一個方法,5還在用;
      SpringBoot2使用的javax到Springboot3之后包統一都換了。但是Shiro,的底層的部分邏輯仍然導入使用的是javax.servlet,就導致包都是重復且混亂的,使用SpringBoot3,引用以及配置的jdk最低都是17,17根本就沒有javax了,就需要導入javax.servlet包 為了適配 Shiro,,導入了又顯示沖突,來來回回,還是太菜。

      解決方案

      反正實現這部分功能肯定需要用上這種安全框架,針對于這個就得出幾種解決方案:

      • 降版本,把SpringBoot從3降到2,自然就好了,網上那么多都是2的,真是,來源是不都是一個人,別的就copy copy;回歸到幸福的jdk1.8;
      • 等,等Shiro的官方在出一個新版本,將現在出現的bug修復掉,就緒使用Shiro;
      • 換!!使用Spring Security,Spring官方這些地方都嵌合的非常好,使用新版Spring也會推出新的其他框架,都是互相適配的,全家桶的舒適感,除了難點都挺好;
      • 把自動裝配去了,手寫配置類去實現;

      手寫

      代碼如下:

      好像還不行.....

      
      package com.demo.config;
      
      import org.apache.shiro.mgt.DefaultSecurityManager;
      import org.apache.shiro.realm.Realm;
      import org.apache.shiro.realm.SimpleAccountRealm;
      import org.apache.shiro.spring.boot.autoconfigure.ShiroAnnotationProcessorAutoConfiguration;
      import org.apache.shiro.spring.boot.autoconfigure.ShiroBeanAutoConfiguration;
      import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration;
      import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.boot.web.servlet.FilterRegistrationBean;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.filter.DelegatingFilterProxy;
      import jakarta.servlet.DispatcherType;
      
      import java.util.EnumSet;
      import java.util.LinkedHashMap;
      import java.util.Map;
      
      /**
       * Apache Shiro 核心配置類
       * 用于集成 Shiro 權限框架到 Spring Boot 3.x 應用
       */
      @Configuration
      @SpringBootApplication(exclude = {
              ShiroBeanAutoConfiguration.class,
              ShiroAnnotationProcessorAutoConfiguration.class,
              ShiroWebFilterConfiguration.class  // 關鍵:禁用有問題的自動配置
      })
      public class ShiroConfigR{
      
      
          public FilterRegistrationBean<DelegatingFilterProxy> shiroFilterRegistration() {
              FilterRegistrationBean<DelegatingFilterProxy> registration = new FilterRegistrationBean<>();
              DelegatingFilterProxy filter = new DelegatingFilterProxy("shiroFilter");
              filter.setTargetFilterLifecycle(true);
              registration.setFilter(filter);
              registration.setEnabled(true);
              registration.addUrlPatterns("/*");
              registration.setOrder(1);
      
              // 使用新 API,不要用 setDispatcherTypes(...)
              // Spring Boot 3 中應使用 setDispatcherTypes 枚舉集合
              registration.setDispatcherTypes(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD));
      
              return registration;
          }
      
          // 使用簡單內存 Realm(生產環境替換為數據庫查詢)
          @Bean
          public Realm realm() {
              SimpleAccountRealm realm = new SimpleAccountRealm();
              // 添加一個測試賬戶
              realm.addAccount("admin", "123456", "admin");
              return realm;
          }
      
          @Bean
          public DefaultSecurityManager securityManager() {
              DefaultSecurityManager  manager = new DefaultSecurityManager ();
              manager.setRealm(realm());
              return manager;
          }
      
          @Bean("shiroFilter")
          public ShiroFilterFactoryBean shiroFilterFactoryBean() {
              ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
              filter.setSecurityManager(securityManager());
      
              // 設置未登錄跳轉登錄頁
              filter.setLoginUrl("/login");
      
              // 登錄成功后跳轉首頁
              filter.setSuccessUrl("/index");
      
              // 無權限跳轉頁
              filter.setUnauthorizedUrl("/unauthorized");
      
              // 配置攔截規則
              Map<String, String> chain = new LinkedHashMap<>();
              chain.put("/login", "anon");
              chain.put("/doLogin", "anon");
              chain.put("/css/**", "anon");
              chain.put("/js/**", "anon");
              chain.put("/favicon.ico", "anon");
              chain.put("/**", "authc"); // 其他路徑需要認證
      
              filter.setFilterChainDefinitionMap(chain);
              return filter;
          }
      
      }
      
      

      繼續排查

      根據成功者的項目學習排查錯誤尋找解決方案,Ruoyi是怎么實現的呢

      前提

      刷git的時候看到了ruoyi,ruoyi同時支持Spring boot2, spring boot3,而且他的權限模塊也是使用的Shiro,去看一看他是怎么實現的。

      參照學習: 插件集成 | RuoYi

      對比項目差別點,檢查自身錯誤

      跟著若依吧他需要的包導進去:

      • 沒有使用shiro-spring-boot-starter;myproject:去掉,會不會使用依賴移動器找不到導致的導入失敗;
      • 重新定義了spring-webspring-webmvc;myproject:引入并指定版本
      • 引入使用了jakarta.servlet-api,沒有javax.servlet-api;myproject:刪掉
      • 為了使用Shiro 單獨引入使用了shiro-core,shiro-spring,shiro-web,在shiro-web排除了shiro-web,并且都指定使用了jakartaclassifier
      • 同一個pom.xml中引入的依賴,同一個包下所使用的版本都是同一個version

      檢查錯誤信息

      1. 發現導入 的Maven倉庫里有兩個spring-web,是不是這里出現的問題

      image

      1. mvn clean install ,清除緩存重新再引入依賴
      2. 刪除不起作用反而會產生干擾的包
          <!-- 引入Shiro BOM統一版本管理(可選但推薦) -->
          <dependencyManagement>
              <dependencies>
                 <dependency>
                     <groupId>org.apache.shiro</groupId>
                     <artifactId>shiro-bom</artifactId>
                     <!-- 使用最新兼容版本 -->
                     <version>${shiro.version}</version> 
                     <type>pom</type>
                     <scope>import</scope>
                 </dependency>
                 <dependency>
                     <groupId>org.springframework</groupId>
                     <artifactId>spring-framework-bom</artifactId>
                     <version>6.2.9</version>
                     <type>pom</type>
                     <scope>import</scope>
                 </dependency>
              </dependencies>
          </dependencyManagement>
      
      1. 重新mvn clean install,檢查依賴,沒有Spring5.3.2的依賴了,可能是解決了
      2. 驗證,檢查各個包中主要使用的類,是否都拋棄了javax換成了Jakarta

      3. 項目啟動測試,沒有問題
      4. 為避免同情況發送,決定統一依賴包 使用<poperites> </poperites>管理


      測試Shiro

      編寫認證授權的Relam

      package com.demo.config;
      
      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.authz.AuthorizationInfo;
      import org.apache.shiro.authz.SimpleAuthorizationInfo;
      import org.apache.shiro.realm.AuthenticatingRealm;
      import org.apache.shiro.realm.AuthorizingRealm;
      import org.apache.shiro.subject.PrincipalCollection;
      
      public class UserRealm extends AuthorizingRealm {
      
          /**
           * 獲取授權信息 授權
           *
           * @param principals 身份憑證集合,包含用戶的身份信息
           * @return AuthorizationInfo 授權信息對象,包含用戶的權限信息
           */
          @Override
          protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
              // 創建簡單的授權信息對象
              SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
      
              // 添加用戶相關權限
              info.addStringPermission("user:add");
              info.addStringPermission("user:delete");
              info.addStringPermission("user:update");
      
              System.out.println("執行了授權-----》");
              return info;
          }
      
          /**
           * 執行身份認證信息獲取操作 認證
           *
           * @param token 認證令牌,包含用戶提交的認證信息
           * @return AuthenticationInfo 認證信息對象,包含正確的用戶名和密碼
           * @throws AuthenticationException 認證異常,當認證過程中出現錯誤時拋出
           */
          @Override
          protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
      
              // 創建簡單的認證信息對象,使用硬編碼的用戶名"admin"和密碼"123456"
              SimpleAuthenticationInfo info = new SimpleAuthenticationInfo("admin", "123456", getName());
      
              System.out.println("執行了認證----》");
      
              return info;
          }
      }
      
      

      控制器

      import org.apache.shiro.authz.annotation.RequiresAuthentication;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.GetMapping;
      
      @Controller
      public class HomeController {
      
          @GetMapping("/index")
          @RequiresAuthentication
          public String index() {
              return "index";
          }
      
          @GetMapping("/unauthorized")
          public String unauthorized() {
              return "unauthorized";
          }
      }
      
      

      跳轉的頁面編寫

      image

      測試

      image

      image

      至此,可算解決了。。。。。

      posted @ 2025-08-13 10:38  柯基大大  閱讀(21)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 亚洲中文一区二区av| 成人精品视频一区二区三区| 中文字幕国产精品av| 日韩精品久久久肉伦网站| 99久久婷婷国产综合精品青草漫画| 色欲AV无码一区二区人妻| 亚洲精品色无码AV试看| 精品乱码一区二区三四五区| 国产国语一级毛片| 亚洲一区成人av在线| 久久精品久久精品久久精品| 国精品91人妻无码一区二区三区| 成人免费在线播放av| 女人香蕉久久毛毛片精品| 五月婷婷中文字幕| 成年午夜免费韩国做受视频| 熟妇人妻久久精品一区二区| 在线看av一区二区三区| 五月天国产成人av免费观看| 中文字幕有码在线第十页| 影视先锋av资源噜噜| 九九热视频在线观看一区| 92精品国产自产在线观看481页| 国产精品va在线观看h| 中文字幕亚洲一区二区三区| 亚洲天堂av日韩精品| 精品国产久一区二区三区| 婷婷四虎东京热无码群交双飞视频 | 日本免费一区二区三区久久| 视频一区视频二区中文字幕| 欧美zoozzooz性欧美| 国产亚洲真人做受在线观看| 国产久免费热视频在线观看| 人妻出轨av中文字幕| 蜜臀av久久国产午夜福利软件| 国产成人午夜精品永久免费| 久久国产av影片| 国产乱码精品一区二区上| 亚洲成人高清av在线| 在线视频中文字幕二区| 亚洲永久精品日韩成人av|