Disabling Keycloak Security in Spring Boot – 在Spring Boot中禁用Keycloak安全

最后修改: 2022年 6月 7日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Keycloak is a free and open-source identity and access management program, often used in our software stacks today. During the testing phase, it may be useful to disable its use to focus on business testing. We may also not have a Keycloak server in our test environment.

Keycloak是一个免费和开源的身份和访问管理程序,在我们今天的软件堆栈中经常使用。在测试阶段,禁用其使用以专注于业务测试可能是有用的。我们的测试环境中也可能没有Keycloak服务器。

In this tutorial, we’ll disable the configuration put in place by the Keycloak starter. We’ll also look at modifying Spring Security when it’s enabled in our project.

在本教程中,我们将禁用Keycloak启动器所设置的配置。我们还将研究如何在项目中启用Spring Security时对其进行修改。

2. Disabling Keycloak in a Non-Spring-Security Environment

2.在非Spring-Security环境中禁用Keycloak

We’ll start by looking at how to disable Keycloak in an application that doesn’t use Spring Security.

我们先来看看如何在不使用Spring Security的应用程序中禁用Keycloak。

2.1. Application Setup

2.1.应用设置

Let’s start by adding the keycloak-spring-boot-starter dependency to our project:

让我们先把keycloak-spring-boot-starter依赖性添加到我们的项目。

<dependency>
    <groupId>org.keycloak</groupId>
    <artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>

Additionally, we need to add the dependencies of the various embedded containers brought by the keycloak-adapter-bom dependency:

此外,我们需要添加由keycloak-adapter-bom依赖性带来的各种嵌入式容器的依赖性。

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.keycloak.bom</groupId>
            <artifactId>keycloak-adapter-bom</artifactId>
            <version>15.0.2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Next, we’ll add to our application.properties the configuration for our Keycloak server:

接下来,我们将在我们的application.properties中添加Keycloak服务器的配置。

keycloak.auth-server-url=http://localhost:8180/auth
keycloak.realm=SpringBootKeycloak
keycloak.resource=login-app
keycloak.public-client=true
keycloak.security-constraints[0].authRoles[0]=user
keycloak.security-constraints[0].securityCollections[0].patterns[0]=/users/*

This configuration ensures that requests to the /users URL will only be accessible to authenticated users with the user role.

该配置确保对/users URL的请求只能由具有user角色的认证用户访问

Finally, let’s add a UserController that retrieves a User:

最后,让我们添加一个UserController,检索一个User

@RestController
@RequestMapping("/users")
public class UserController {
    @GetMapping("/{userId}")
    public User getCustomer(@PathVariable Long userId) {
        return new User(userId, "John", "Doe");
    }
}

2.2. Disabling Keycloak

2.2.禁用Keycloak

Now that our application is in place, let’s write a simple test to get a user:

现在我们的应用程序已经到位,让我们写一个简单的测试来获取一个用户。

@Test
public void givenUnauthenticated_whenGettingUser_shouldReturnUser() {
    ResponseEntity<User> responseEntity = restTemplate.getForEntity("/users/1", User.class);

    assertEquals(HttpStatus.SC_OK, responseEntity.getStatusCodeValue());
    assertNotNull(responseEntity.getBody()
        .getFirstname());
}

This test will fail because we didn’t provide any authentication to restTemplate, or because the Keycloak server is not available.

这个测试将失败,因为我们没有向restTemplate提供任何认证,或者因为Keycloak服务器不可用。

The Keycloak adapter implements the Spring autoconfiguration of Keycloak security. Autoconfigurations rely on the presence of a class in the classpath or on the value of a property. Specifically, the @ConditionalOnProperty annotation is very handy for this particular need.

Keycloak适配器实现了Keycloak安全的Spring自动配置>。自动配置依赖于classpath中的一个类的存在,或者依赖于一个属性的值。具体来说,@ConditionalOnProperty注解对这种特殊需求非常方便。

To disable Keycloak security, we need to inform the adapter that it should not load the corresponding configuration. We can do this by assigning the property as follows:

为了禁用Keycloak安全,我们需要通知适配器它不应该加载相应的配置。我们可以通过分配属性来做到这一点,如下所示。

keycloak.enabled=false

If we launch our test again, it will now succeed without any authentication involved.

如果我们再次启动我们的测试,现在它将在没有任何认证的情况下成功。

3. Disabling Keycloak in a Spring Security Environment

3.在Spring安全环境中禁用Keycloak

We often use Keycloak in combination with Spring Security. In this case, it’s not enough to disable the Keycloak configuration, but we also need to modify the Spring Security configuration to allow anonymous requests to reach the controllers.

我们经常使用Keycloak与Spring Security的组合。在这种情况下,仅仅禁用Keycloak配置是不够的,我们还需要修改Spring Security配置以允许匿名请求到达控制器。

3.1. Application Setup

3.1.应用设置

Let’s start by adding the spring-boot-starter-security dependency to our project:

让我们首先将spring-boot-starter-security依赖性添加到我们的项目中。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Next, we implement the WebSecurityConfigurerAdapter to define the configuration needed for Spring Security. The Keycloak adapter provides an abstract class and annotation that for this purpose:

接下来,我们实现WebSecurityConfigurerAdapter来定义Spring Security所需的配置。Keycloak适配器提供了一个抽象类和注解,用于此目的。

@KeycloakConfiguration
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(keycloakAuthenticationProvider());
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new NullAuthenticatedSessionStrategy();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);

        http.csrf()
            .disable()
            .authorizeRequests()
            .anyRequest()
            .authenticated();
    }
}

Here, we’re configuring Spring Security to allow requests from authenticated users only.

在这里,我们将Spring Security配置为只允许来自认证用户的请求。

3.2. Disabling Keycloak

3.2.禁用Keycloak

As well as disabling Keycloak like we did earlier, we now also need to disable Spring Security.

除了像我们之前做的那样禁用Keycloak,我们现在还需要禁用Spring Security

We could use profiles to tell Spring whether or not to activate the Keycloak configuration during our tests:

我们可以使用profiles来告诉Spring是否在我们的测试中激活Keycloak配置。

@KeycloakConfiguration
@Profile("tests")
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
    // ...
}

However, a more elegant way is to reuse the keycloak.enable property, similar to the Keycloak adapter:

然而,一个更优雅的方法是重用keycloak.enable属性,类似于Keycloak适配器。

@KeycloakConfiguration
@ConditionalOnProperty(name = "keycloak.enabled", havingValue = "true", matchIfMissing = true)
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
    // ...
}

As a result, Spring only enables Keycloak configuration if the keycloak.enable property is true. In case the property is missing, matchIfMissing enables it by default.

因此,Spring只在keycloak.enable属性为true时启用Keycloak配置。如果该属性缺失,matchIfMissing会默认启用它。

As we’re using the Spring Security starter, it’s not enough to disable our Spring Security configuration. Indeed, following Spring’s opinionated defaults configuration principles, the starter will create a default security layer.

由于我们使用的是Spring Security启动器,所以仅仅禁用Spring Security配置是不够的。事实上,遵循Spring的意见默认配置原则,启动器将创建一个默认的安全层

Let’s create a configuration class to disable it:

让我们创建一个配置类来禁用它。

@Configuration
@ConditionalOnProperty(name = "keycloak.enabled", havingValue = "false")
public class DisableSecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf()
            .disable()
            .authorizeRequests()
            .anyRequest()
            .permitAll();
       return http.build();
    }
}

We’re still using our keycloak.enable property, but this time Spring enables the configuration if its value is set to false.

我们仍然使用我们的keycloak.enable属性,但这次如果其值被设置为false,Spring将启用该配置。

4. Conclusion

4.总结

In this article, we looked at how to disable Keycloak security in a Spring environment, with or without Spring Security.

在这篇文章中,我们研究了如何在Spring环境中禁用Keycloak安全,无论是否有Spring Security。

As usual, all the code samples used in this article can be found over on GitHub.

像往常一样,本文中使用的所有代码样本都可以在GitHub上找到over