【问题标题】:Spring Boot - How to disable Keycloak?Spring Boot - 如何禁用 Keycloak?
【发布时间】:2018-05-31 09:15:24
【问题描述】:

我有一个集成了 keycloak 的 Spring Boot 项目。现在我想禁用 keycloak 以进行测试。

我尝试将 keycloak.enabled=false 添加到 application.properties,如 Keycloak documentation 中所述,但没有成功。

那么我该如何禁用它呢?

【问题讨论】:

  • 您是否尝试从 Maven 的 gradle 构建文件的依赖项部分中删除 keycloak-spring-boot-starter?
  • 没有。我实际上想在不删除 keycloak 依赖项的情况下禁用它。
  • 问题解决了吗?我想在 Spring Boot 控制器测试中禁用它,但该线程中的解决方案不起作用。
  • 我刚刚在下面发布了我的解决方案。请看一看。

标签: spring spring-boot keycloak


【解决方案1】:

它应该可以工作,但根据jira ticket 上的最后一条评论,它似乎不是。

作为描述状态,您可以将 keycloak 的 spring boot 自动配置添加到您的application.propertiesspring.autoconfigure.exclude=org.keycloak.adapters.springboot.KeycloakSpringBootConfiguration

【讨论】:

  • 如果您还启用了 Spring Security,则它不起作用,enable 标志仅适用于单独使用的 Spring Boot Adapter。当使用 Spring Secuiryt 时,我们还有一张支持 flag 的票。
【解决方案2】:

您需要排除 keycloak 自动配置。为此,只需将此条目添加到相关的 spring 配置文件中,在您的情况下为 application.properties。

spring.autoconfigure.exclude = org.keycloak.adapters.springboot.KeycloakAutoConfiguration

【讨论】:

    【解决方案3】:

    对于可能遇到同样问题的任何人,这就是我所做的。

    我没有禁用 Keycloak,但我制作了一个单独的 Keycloak 配置文件用于测试目的。

    这是我的配置文件

    @Profile("test")
    @Configuration
    @EnableWebSecurity
    public class SecurityTestConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().antMatchers("/**").permitAll();
            http.headers().frameOptions().disable();
            http.csrf().disable();
    
        }
    
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/**");
        }
    
        @Bean
        @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
        public AccessToken accessToken() {
            AccessToken accessToken = new AccessToken();
            accessToken.setSubject("abc");
            accessToken.setName("Tester");
    
            return accessToken;
    
        }
    
    }
    

    请注意,仅在测试环境中使用它很重要,因此我将配置注释为@Profile("test")。我还添加了一个 AccessToken bean,因为我的应用程序中的一些审计功能依赖于它。

    【讨论】:

      【解决方案4】:

      我的解决方法:

      1. 创建一个自定义过滤器并将其添加到(Spring)安全链的早期位置。
      2.在application.yml中创建flag(securityEnabled)
      3. 查询自定义过滤器中的标志。如果为“真”,只需调用chain.doFilter() 继续下一个过滤器。如果为“假”,则创建一个虚拟 Keycloak-Account 设置您需要的角色并将其设置为上下文。
      4.顺便把角色也外包给了application.yml
      5. 跳过安全链中的其余过滤器(因此不执行 keycloak-stuff 并且发生相应的授权)

      详细:

      1.自定义过滤器类

      public class CustomFilter extends OncePerRequestFilter {
      
        @Value("${securityEnabled}")
        private boolean securityEnabled;
      
        @Value("${grantedRoles}")
        private String[] grantedRoles;
      
        @Override
        public void doFilterInternal(HttpServletRequest req, HttpServletResponse res,
                             FilterChain chain) throws IOException, ServletException {
      
            if (!securityEnabled){
                // Read roles from application.yml
                Set<String> roles = Arrays.stream(grantedRoles)
                        .collect(Collectors.toCollection(HashSet::new));
                // Dummy Keycloak-Account
                RefreshableKeycloakSecurityContext session = new RefreshableKeycloakSecurityContext(null, null, null, null, null, null, null);
                final KeycloakPrincipal<RefreshableKeycloakSecurityContext> principal = new KeycloakPrincipal<>("Dummy_Principal", session);
                final KeycloakAccount account = new SimpleKeycloakAccount(principal, roles, principal.getKeycloakSecurityContext());
                // Dummy Security Context
                SecurityContext context = SecurityContextHolder.createEmptyContext();
                context.setAuthentication(new KeycloakAuthenticationToken(account, false));
                SecurityContextHolder.setContext(context);
      
                // Skip the rest of the filters
                req.getRequestDispatcher(req.getServletPath()).forward(req, res);
            }
      
            chain.doFilter(req, res);
        }
      }
      


      2. 在 Spring-Security 的 http-Configuration 中插入 Custom-Filter

      protected void configure(HttpSecurity http) throws Exception {
          super.configure(http);
          http
                  .cors()
                  .and()
                  .csrf()
                  .disable()
                  .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                  .sessionAuthenticationStrategy(sessionAuthenticationStrategy())
                  .and()
                  .addFilterAfter(CustomFilter(), CsrfFilter.class)
                  .authorizeRequests()
                  .anyRequest().permitAll();
      }
      

      配置Keycloak后看看默认的Filter-Chain:

      Filter-Chain

      所以很明显在位置 5 插入自定义过滤器以避免整个 Keycloak-Magic。

      我已使用此解决方法来破坏方法安全性,它是@Secured-Annotation。

      【讨论】:

      • 那么如何再次启用 Keycloak?通过注释掉过滤器?
      • 通过在 application.yml 中设置标志 securityEnabled = true。然后过滤器中的 if-Statement 被跳过。
      • 什么是“.sessionAuthenticationStrategy(sessionAuthenticationStrategy())”?如何定义方法 sessionAuthenticationStrategy()?
      • 我无法让这种方法发挥作用.. 我的自定义过滤器的“doFilterInternal”方法永远不会被调用,即使过滤器本身已在链上的正确位置注册。尝试直接实现过滤器或扩展 GenericFilterBean。 “doFilter”从未被调用...
      猜你喜欢
      • 2017-11-28
      • 2021-08-11
      • 1970-01-01
      • 2020-06-02
      • 2022-08-10
      • 2016-09-27
      • 2019-05-31
      • 2019-06-07
      • 2020-01-11
      相关资源
      最近更新 更多