日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Shiro】Unsatisfied dependency expressed through method 'securityManager' parameter 3

發布時間:2023/12/10 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Shiro】Unsatisfied dependency expressed through method 'securityManager' parameter 3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,我是烤鴨:

? ? ? 采坑記錄,springboot 整合 shiro。

? ? ? 環境:

? ? ? ?springboot? ??2.0.5.RELEASE

? ? ? ?shiro-spring? ? 1.4.0

? ? ? ?shiro-redis? ? 3.1.0

1.問題

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'shiroFilter' defined in class path resource [com/test/shiro/ShiroConfig.class]: Unsatisfied dependency expressed through method 'shiroFilter' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name'securityManager' defined in class path resource [com/test/shiro/ShiroConfig.class]: Unsatisfied dependency expressed through method 'securityManager' parameter 3; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.crazycake.shiro.RedisCacheManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

2.原因

? ? 按異常信息去百度查結果,效果不理想。同事本地試過是沒有問題的,合代碼的時候出現了問題。爭取少改動代碼解決問題。
?? ?發現不太好改,找不到問題在哪。

? ? 代碼重現。主要是

? ? ShiroConfig.java

package com.test.shiro;import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.RememberMeManager; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.CookieRememberMeManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.Cookie; import org.apache.shiro.web.servlet.SimpleCookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.crazycake.shiro.RedisCacheManager; import org.crazycake.shiro.RedisManager; import org.crazycake.shiro.RedisSessionDAO; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn;import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map;@Slf4j public class ShiroConfig {@Value("${spring.redis.host}")private String redisHost;@Value("${spring.redis.port}")private Integer redisPort;/*@Value("${spring.redis.password}")private String redisPassword;*/@Value("${spring.redis.timeout}")private Integer redisTimeout;@Beanpublic ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//設置安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);//默認跳轉到登陸頁面shiroFilterFactoryBean.setLoginUrl("/test/web/sysUser/noLogin");//登陸成功后的頁面shiroFilterFactoryBean.setSuccessUrl("/test/web/sysUser/loginSuccess");shiroFilterFactoryBean.setUnauthorizedUrl("/403");//自定義過濾器Map<String, Filter> filterMap = new LinkedHashMap<>();shiroFilterFactoryBean.setFilters(filterMap);// 權限控制mapMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();// 配置不會被攔截的鏈接 順序判斷// 配置登錄方法不被攔截filterChainDefinitionMap.put("/web/login", "anon");filterChainDefinitionMap.put("/test/web/login", "anon");filterChainDefinitionMap.put("/test/web/sysUser/login", "anon");filterChainDefinitionMap.put("/web/sysUser/login", "anon");filterChainDefinitionMap.put("/test/web/sysUser/code", "anon");filterChainDefinitionMap.put("/test/web/sysUser/verification/code", "anon");filterChainDefinitionMap.put("/test/web/sysUser/addSysUser", "anon");// 配置APP接口不被攔截filterChainDefinitionMap.put("/test/app/**", "anon");// 配置靜態頁面不被攔截 // filterChainDefinitionMap.put("/static/**", "anon");// 配置退出過濾器,其中的具體的退出代碼Shiro已經替我們實現了filterChainDefinitionMap.put("/logout", "logout");// 過濾鏈定義,從上向下順序執行,一般將/**放在最為下邊。// authc:所有url都必須認證通過才可以訪問; anon:所有url都都可以匿名訪問filterChainDefinitionMap.put("/**", "authc"); // 攔截所有鏈接shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);return shiroFilterFactoryBean;}/*** 核心的安全事務管理器* 設置realm、cacheManager等*/@Bean(name = "securityManager")public SecurityManager securityManager(ShiroRealm shiroRealm, SessionManager sessionManager, RememberMeManager rememberMeManager, RedisCacheManager cacheManager){DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();// 設置 RealmsecurityManager.setRealm(shiroRealm);// 記住密碼管理器securityManager.setRememberMeManager(rememberMeManager);// 自定義session管理 使用redissecurityManager.setSessionManager(sessionManager);// 自定義緩存實現 使用redissecurityManager.stestacheManager(cacheManager);return securityManager;}/*** Session的管理*/@Bean(name = "sessionManager")public DefaultWebSessionManager sessionManager(RedisSessionDAO redisSessionDAO) {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setSessionDAO(redisSessionDAO);// 設置session過期時間為1小時(單位:毫秒),默認為30分鐘sessionManager.setGlobalSessionTimeout(60 * 60 * 1000);sessionManager.setSessionValidationSchedulerEnabled(true);return sessionManager;}/*** 身份認證Realm,此處的注入不可以缺少。否則會在UserRealm中注入對象會報空指針.*/@Bean(name = "shiroRealm")public ShiroRealm shiroRealm(HashedCredentialsMatcher hashedCredentialsMatcher){ShiroRealm myShiroRealm = new ShiroRealm();myShiroRealm.stestredentialsMatcher(hashedCredentialsMatcher);return myShiroRealm;}/*** 哈希密碼比較器。在ShiroRealm中作用參數使用* 登陸時會比較用戶輸入的密碼,跟數據庫密碼配合鹽值salt解密后是否一致。*/@Bean(name = "hashedCredentialsMatcher")public HashedCredentialsMatcher hashedCredentialsMatcher(){HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();hashedCredentialsMatcher.setHashAlgorithmName("md5"); //散列算法:這里使用md5算法;hashedCredentialsMatcher.setHashIterations(2); //散列的次數,比如散列兩次,相當于 md5(md5(""));return hashedCredentialsMatcher;}/*** 配置自定義的密碼比較器*/@Bean(name = "credentialsMatcher")public CredentialsMatcher credentialsMatcher(){return new CredentialsMatcher();}/*** 配置shiro redisManager* 使用的是shiro-redis開源插件*/@Bean(name = "redisManager")public RedisManager redisManager() {RedisManager redisManager = new RedisManager();redisManager.setHost(redisHost);redisManager.setPort(redisPort);// redisManager.setPassword(redisPassword);//redisManager.setExpire(1800); // 配置緩存過期時間redisManager.setTimeout(redisTimeout);return redisManager;}/*** cacheManager 緩存 redis實現* 使用的是shiro-redis開源插件*/@Bean(name = "cacheManager")public RedisCacheManager cacheManager(RedisManager redisManager) {RedisCacheManager redisCacheManager = new RedisCacheManager();redisCacheManager.setRedisManager(redisManager);//redisCacheManager.getRedisManager()return redisCacheManager;}/*** RedisSessionDAO shiro sessionDao層的實現 通過redis* 使用的是shiro-redis開源插件*/@Bean(name = "redisSessionDAO")public RedisSessionDAO redisSessionDAO(RedisManager redisManager) {RedisSessionDAO redisSessionDAO = new RedisSessionDAO();redisSessionDAO.setRedisManager(redisManager);return redisSessionDAO;}/*** 記住我管理器*/@Bean(name = "rememberMeManager")public CookieRememberMeManager rememberMeManager(Cookie rememberMeCookie) {CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.stestookie(rememberMeCookie);// rememberMe cookie加密的密鑰 默認AES算法 // cookieRememberMeManager.stestipherKey();return cookieRememberMeManager;}/*** cookie對象*/@Bean(name = "rememberMeCookie")public Cookie rememberMeCookie() {SimpleCookie simpleCookie = new SimpleCookie("rememberMe");// 記住我cookie生效時間,單位:秒simpleCookie.setMaxAge(3600);return simpleCookie;}/*** 開啟shiro aop注解支持.* 使用代理方式;所以需要開啟代碼支持;否則@RequiresRoles等注解無法生效*/@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}/*** Shiro生命周期處理器*/@Beanpublic static LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){return new LifecycleBeanPostProcessor();}/*** 自動創建代理*/@Bean@DependsOn({"lifecycleBeanPostProcessor"})public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargtestlass(true);return advisorAutoProxyCreator;} }

根據報錯信息和上面的代碼找問題。異常都是從下往上看的。
源頭:
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.crazycake.shiro.RedisCacheManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

RedisCacheManager 沒注入,所以用到的地方會報錯。
用到的地方是 securityManager(ShiroRealm shiroRealm, SessionManager sessionManager, RememberMeManager rememberMeManager, RedisCacheManager cacheManager) 構造方法的第三個參數
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityManager' defined in class path resource [com/test/shiro/ShiroConfig.class]: Unsatisfied dependency expressed through method 'securityManager' parameter 3。
問題找到就好解決了。
改寫構造方法。改后的shiroConfig.java如下。

package com.etc.shiro;import lombok.extern.slf4j.Slf4j; import org.apache.shiro.authc.credential.HashedCredentialsMatcher; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.CookieRememberMeManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.Cookie; import org.apache.shiro.web.servlet.SimpleCookie; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.crazycake.shiro.RedisCacheManager; import org.crazycake.shiro.RedisManager; import org.crazycake.shiro.RedisSessionDAO; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn;import javax.servlet.Filter; import java.util.LinkedHashMap; import java.util.Map;@Slf4j @Configuration public class ShiroConfig {@Value("${spring.redis.host}")private String redisHost;@Value("${spring.redis.port}")private Integer redisPort;@Value("${spring.redis.password}")private String redisPassword;@Value("${spring.redis.timeout}")private Integer redisTimeout;@Beanpublic ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();//自定義過濾器Map<String, Filter> filterMap = new LinkedHashMap<>();shiroFilterFactoryBean.setFilters(filterMap);// 權限控制mapLinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();// 配置不會被攔截的鏈接 順序判斷// 配置登錄方法不被攔截filterChainDefinitionMap.put("/invoke/*", "anon");filterChainDefinitionMap.put("/web/login", "anon");filterChainDefinitionMap.put("/etc/web/login", "anon");filterChainDefinitionMap.put("/etc/web/sysUser/login", "anon");filterChainDefinitionMap.put("/web/sysUser/login", "anon");filterChainDefinitionMap.put("/web/sysUser/getcode", "anon");filterChainDefinitionMap.put("/etc/web/sysUser/verification/code", "anon");filterChainDefinitionMap.put("/etc/web/sysUser/addSysUser", "anon");// 配置APP接口不被攔截filterChainDefinitionMap.put("/etc/app/**", "anon");// 配置靜態頁面不被攔截filterChainDefinitionMap.put("/static/**", "anon");// 配置退出過濾器,其中的具體的退出代碼Shiro已經替我們實現了filterChainDefinitionMap.put("/logout", "logout");// 過濾鏈定義,從上向下順序執行,一般將/**放在最為下邊。// authc:所有url都必須認證通過才可以訪問; anon:所有url都都可以匿名訪問//· filterChainDefinitionMap.put("/**", "authc"); // 攔截所有鏈接shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);//設置安全管理器shiroFilterFactoryBean.setSecurityManager(securityManager);//默認跳轉到登陸頁面shiroFilterFactoryBean.setLoginUrl("/etc/web/sysUser/noLogin");//登陸成功后的頁面shiroFilterFactoryBean.setSuccessUrl("/etc/web/sysUser/loginSuccess");shiroFilterFactoryBean.setUnauthorizedUrl("/403");return shiroFilterFactoryBean;}/*** 核心的安全事務管理器* 設置realm、cacheManager等*/@Beanpublic SecurityManager securityManager(ShiroRealm shiroRealm){DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();// 設置 RealmsecurityManager.setRealm(shiroRealm);// 記住密碼管理器securityManager.setRememberMeManager(rememberMeManager());// 自定義session管理 使用redissecurityManager.setSessionManager(sessionManager());// 自定義緩存實現 使用redissecurityManager.setCacheManager(redisCacheManager());return securityManager;}/*** Session的管理*/@Bean(name = "sessionManager")public DefaultWebSessionManager sessionManager() {DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();sessionManager.setSessionDAO(redisSessionDAO());// 設置session過期時間為1小時(單位:毫秒),默認為30分鐘sessionManager.setGlobalSessionTimeout(60 * 60 * 1000);sessionManager.setSessionValidationSchedulerEnabled(true);return sessionManager;}/*** 身份認證Realm,此處的注入不可以缺少。否則會在UserRealm中注入對象會報空指針.*/@Beanpublic ShiroRealm shiroRealm(){ShiroRealm myShiroRealm = new ShiroRealm();myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());return myShiroRealm;}/*** 哈希密碼比較器。在ShiroRealm中作用參數使用* 登陸時會比較用戶輸入的密碼,跟數據庫密碼配合鹽值salt解密后是否一致。*/@Bean(name = "hashedCredentialsMatcher")public HashedCredentialsMatcher hashedCredentialsMatcher(){HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();hashedCredentialsMatcher.setHashAlgorithmName("md5"); //散列算法:這里使用md5算法;hashedCredentialsMatcher.setHashIterations(2); //散列的次數,比如散列兩次,相當于 md5(md5(""));return hashedCredentialsMatcher;}/*** 配置自定義的密碼比較器*/@Bean(name = "credentialsMatcher")public CredentialsMatcher credentialsMatcher(){return new CredentialsMatcher();}// /** // * Shiro 緩存管理器 // * 需要注入對應的其它的實體類中: 安全管理器:securityManager // * 可見securityManager是整個shiro的核心; // */ // @Bean // public EhCacheManager ehCacheManager(){ // logger.info("------------->ShiroConfiguration.getEhCacheManager()執行"); // EhCacheManager cacheManager = new EhCacheManager(); // cacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml"); // return cacheManager; // }/*** 配置shiro redisManager* 使用的是shiro-redis開源插件*/@Bean(name = "redisManager")public RedisManager redisManager() {RedisManager redisManager = new RedisManager();redisManager.setHost(redisHost);redisManager.setPort(redisPort);redisManager.setPassword(redisPassword);//redisManager.setExpire(1800); // 配置緩存過期時間redisManager.setTimeout(redisTimeout);return redisManager;}/*** cacheManager 緩存 redis實現* 使用的是shiro-redis開源插件*/@Beanpublic RedisCacheManager redisCacheManager() {RedisCacheManager redisCacheManager = new RedisCacheManager();redisCacheManager.setRedisManager(redisManager());return redisCacheManager;}/*** RedisSessionDAO shiro sessionDao層的實現 通過redis* 使用的是shiro-redis開源插件*/@Beanpublic RedisSessionDAO redisSessionDAO() {RedisSessionDAO redisSessionDAO = new RedisSessionDAO();redisSessionDAO.setRedisManager(redisManager());return redisSessionDAO;}/*** 記住我管理器*/@Beanpublic CookieRememberMeManager rememberMeManager() {CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.setCookie(rememberMeCookie());// rememberMe cookie加密的密鑰 默認AES算法 // cookieRememberMeManager.setCipherKey();return cookieRememberMeManager;}/*** cookie對象*/@Beanpublic Cookie rememberMeCookie() {SimpleCookie simpleCookie = new SimpleCookie("rememberMe");// 記住我cookie生效時間,單位:秒simpleCookie.setMaxAge(3600);return simpleCookie;}/*** 開啟shiro aop注解支持.* 使用代理方式;所以需要開啟代碼支持;否則@RequiresRoles等注解無法生效*/@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);return authorizationAttributeSourceAdvisor;}/*** Shiro生命周期處理器*/@Beanpublic static LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){return new LifecycleBeanPostProcessor();}/*** 自動創建代理*/@Bean@DependsOn({"lifecycleBeanPostProcessor"})public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();advisorAutoProxyCreator.setProxyTargetClass(true);return advisorAutoProxyCreator;} }

遇到問題時,沒有搜索到特別好的解決方式時。
并沒有根據報錯信息仔細查找問題源頭(主要也是因為看不懂),應該優先分析報錯信息,這樣會解決的比較快。
?

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的【Shiro】Unsatisfied dependency expressed through method 'securityManager' parameter 3的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。