You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by GitBox <gi...@apache.org> on 2021/04/21 06:37:31 UTC

[GitHub] [shardingsphere] BingYu-track opened a new issue #10146: Why "org.apache.shardingsphere.spring.boot.SpringBootConfiguration" dependence on my shiro bean "shiroFilter"?

BingYu-track opened a new issue #10146:
URL: https://github.com/apache/shardingsphere/issues/10146


   ## Question
   
   env:springboot2.3.5
   version:sharding-jdbc 5.0.0
   **The dependencies of some of the beans in the application context form a cycle:**
   ![image](https://user-images.githubusercontent.com/33021175/115507062-34df7100-a2ae-11eb-914e-dfab81f0a470.png)
   
   **This is my shiro config:**
   ```java
   /**
    * Shiro配置类
    */
   @Configuration
   //@PropertySource("classpath:redis.properties")
   @Data
   public class ShiroConfig {
   
       private final String CACHE_KEY = "shiro:cache:";
       private final String SESSION_KEY = "shiro:session:";
       private Integer EXPIRE = 86400 * 7;
   
       @Value("${spring.redis.host}")
       private String host;
       @Value("${spring.redis.port}")
       private Integer port;
       @Value("${spring.redis.password}")
       private String password;
       @Value("${spring.redis.timeout}")
       private Integer timeout;
   
       @Bean
       public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
           ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
           shiroFilterFactoryBean.setSecurityManager(securityManager);
           // 过滤器链定义映射
           Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
           /*
            * anon:所有url都都可以匿名访问,authc:所有url都必须认证通过才可以访问;
            * 过滤链定义,从上向下顺序执行,authc 应放在 anon 下面
            * */
           filterChainDefinitionMap.put("/common/**", "anon");
           filterChainDefinitionMap.put("/login/**", "anon");
           filterChainDefinitionMap.put("/druid/**", "anon");
           // 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录
           filterChainDefinitionMap.put("/css/**", "anon");
           filterChainDefinitionMap.put("/fonts/**", "anon");
           filterChainDefinitionMap.put("/img/**", "anon");
           filterChainDefinitionMap.put("/js/**", "anon");
           filterChainDefinitionMap.put("/html/**", "anon");
           filterChainDefinitionMap.put("/images/**", "anon");
           //swagger接口权限 开放
           filterChainDefinitionMap.put("/swagger-ui.html", "anon");
           filterChainDefinitionMap.put("/swagger/**", "anon");
           filterChainDefinitionMap.put("/webjars/**", "anon");
           filterChainDefinitionMap.put("/swagger-resources/**", "anon");
           filterChainDefinitionMap.put("/v2/**", "anon");
           filterChainDefinitionMap.put("/doc.html", "anon");
           // 所有url都必须认证通过才可以访问
           filterChainDefinitionMap.put("/**", "authc");
   
           // 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了, 位置放在 anon、authc下面
           filterChainDefinitionMap.put("/login/logout", "logout");
   
           // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
           // 配器shirot认登录累面地址,前后端分离中登录累面跳转应由前端路由控制,后台仅返回json数据, 对应LoginController中unauth请求
           shiroFilterFactoryBean.setLoginUrl("/login/un_auth");
           Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
           filters.put("authc", new ShiroLoginFilter());
           // 退出过滤器
           filters.put("logout", logoutFilter());
   //        shiroFilterFactoryBean.setFilters(filters);
   
           // 登录成功后要跳转的链接, 此项目是前后端分离,故此行注释掉,登录成功之后返回用户基本信息及token给前端
           // shiroFilterFactoryBean.setSuccessUrl("/index");
   
           // 未授权界面, 对应LoginController中 unauthorized 请求
           shiroFilterFactoryBean.setUnauthorizedUrl("/login/unauthorized");
   
   //        // 自动跳去登录的地址
   //        shiroFilterFactoryBean.setLoginUrl("/login");
   //        // 未授权页面
   //        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
   
           shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
           return shiroFilterFactoryBean;
       }
   
   
       /**
        * 凭证匹配器(由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了)
        * 下面调用了自定义的验证类 这个方法就没有了
        *
        * @return
        */
       @Bean
       public HashedCredentialsMatcher hashedCredentialsMatcher() {
           HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
           //散列算法:这里使用MD5算法
           hashedCredentialsMatcher.setHashAlgorithmName("md5");
           //散列的次数,比如散列两次,相当于md5(md5(""))
           hashedCredentialsMatcher.setHashIterations(1);
           return hashedCredentialsMatcher;
       }
   
       /**
        * 将自己的验证方式加入容器
        *
        * @return
        */
       @Bean
       public MyShiroRealm myShiroRealm() {
           MyShiroRealm myShiroRealm = new MyShiroRealm();
           myShiroRealm.setCredentialsMatcher(new CustomCredentialsMatcher());
           return myShiroRealm;
       }
   
       /**
        * RedisSessionDAOI shiro sessionDao层的实现 通过redis,使用的是shiro-redis开源插件
        *
        * @return
        */
       @Bean
       public RedisSessionDAO redisSessionDAO() {
           RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
           redisSessionDAO.setRedisManager(redisManager());
           redisSessionDAO.setSessionIdGenerator(sessionIdGenerator());
           redisSessionDAO.setKeyPrefix(SESSION_KEY);
           redisSessionDAO.setExpire(EXPIRE);
           return redisSessionDAO;
       }
   
       /**
        * Session ID生成器
        *
        * @return
        */
       @Bean
       public JavaUuidSessionIdGenerator sessionIdGenerator() {
           return new JavaUuidSessionIdGenerator();
       }
   
       /**
        * 自定义的sessionManager
        *
        * @return
        */
       @Bean
       public SessionManager sessionManager() {
           MySessionManager mySessionManager = new MySessionManager();
           mySessionManager.setSessionDAO(redisSessionDAO());
           mySessionManager.setGlobalSessionTimeout(86400000L);
           return mySessionManager;
       }
   
       /**
        * 配置shiro RedisManager,使用的是shiro-redis开源插件
        *
        * @return
        */
       private RedisManager redisManager() {
           RedisManager redisManager = new RedisManager();
           redisManager.setHost(host);
           redisManager.setPort(port);
           redisManager.setTimeout(timeout);
           if (!StringUtils.isEmpty(password)) {
               redisManager.setPassword(password);
           }
           return redisManager;
       }
   
       /**
        * 缓存redis实现,使用的shiro-redis开源查看
        *
        * @return
        */
       @Bean
       public RedisCacheManager cacheManager() {
           RedisCacheManager redisCacheManager = new RedisCacheManager();
           redisCacheManager.setRedisManager(redisManager());
           redisCacheManager.setKeyPrefix(CACHE_KEY);
           // 配置缓存的话要求放在session里面的实体类必须有个id标识
           redisCacheManager.setPrincipalIdFieldName("id");
           return redisCacheManager;
       }
   
       /**
        * 安全管理器,授权管理,配置主要是Realm的管理认证
        *
        * @return
        */
       @Bean
       public SecurityManager securityManager() {
           DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
           // 自定义session管理 使用redis,将自定义的会话管理器注册到安全管理器中
           securityManager.setSessionManager(sessionManager());
           // 自定义缓存实现 使用redis,将自定义的redis缓存管理器注册到安全管理器中
           securityManager.setCacheManager(cacheManager());
           // 自定义Realm验证
           securityManager.setRealm(myShiroRealm());
           // 记住我
           securityManager.setRememberMeManager(rememberMeManager());
           return securityManager;
       }
   
       /**
        * 记住我
        */
       public CookieRememberMeManager rememberMeManager() {
           CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
           cookieRememberMeManager.setCookie(cookie());
           cookieRememberMeManager.setCipherKey(Base64.decode("fCq+/xW488hMTCD+cmJ3aQ=="));
           return cookieRememberMeManager;
       }
   
       /**
        * 退出过滤器
        *
        * @return
        */
       public ShiroLogoutFilter logoutFilter() {
           ShiroLogoutFilter logoutFilter = new ShiroLogoutFilter();
           return logoutFilter;
       }
   
       /**
        * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
        * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
        *
        * @return
        */
       @Bean
       public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
           DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
           advisorAutoProxyCreator.setProxyTargetClass(true);
           return advisorAutoProxyCreator;
       }
   
       @Bean
       public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
           AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
           authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
           return authorizationAttributeSourceAdvisor;
       }
   
       @Bean
       public SimpleCookie cookie() {
           //cookie的name,对应的默认是JSESSIONID
           SimpleCookie cookie = new SimpleCookie("SHARE_JSESSIONID");
           cookie.setHttpOnly(true);
           //path 为/ 用于多个系统共享JSESSIONID
           cookie.setPath("/");
           return cookie;
       }
   
   }
   ```
   
   **Who can tell me why "org.apache.shardingsphere.spring.boot.SpringBootConfiguration" dependence on my shiro bean "shiroFilter"?**


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [shardingsphere] BingYu-track commented on issue #10146: Why "org.apache.shardingsphere.spring.boot.SpringBootConfiguration" dependence on my shiro bean "shiroFilter"?

Posted by GitBox <gi...@apache.org>.
BingYu-track commented on issue #10146:
URL: https://github.com/apache/shardingsphere/issues/10146#issuecomment-823909924


   I solved this prolem! We need add @Lazy in my shiro Realm. It can help create sharding-jdbc datasource before shiro's datasource.
   ![image](https://user-images.githubusercontent.com/33021175/115528597-c5c14700-a2c4-11eb-8f7e-5d0f0ac2033d.png)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [shardingsphere] BingYu-track closed issue #10146: Why "org.apache.shardingsphere.spring.boot.SpringBootConfiguration" dependence on my shiro bean "shiroFilter"?

Posted by GitBox <gi...@apache.org>.
BingYu-track closed issue #10146:
URL: https://github.com/apache/shardingsphere/issues/10146


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org