禁用 Spring Boot 中的 Keycloak 安全功能

Spring Security
Remote
1
07:08 AM · Nov 30 ,2025

1. 概述

Keycloak 是一個免費且開源的身份和訪問管理程序,經常被用於我們今天的軟件堆棧中。在測試階段,禁用其使用可能有助於我們專注於業務測試。我們可能在測試環境中沒有 Keycloak 服務器。

在本教程中,我們將禁用 Keycloak 啓動器中配置的設置。我們還將研究在項目啓用 Spring Security 時如何修改它。

2. 取消啓用 Keycloak 在非 Spring Security 環境中

我們首先來看一下在不使用 Spring Security 的應用程序中如何禁用 Keycloak。

2.1. 應用程序設置

讓我們首先將 spring-boot-starter-oauth2-client 依賴添加到我們的項目:

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

此外,我們需要添加 spring-boot-starter-oauth2-resource-server 依賴。這將允許我們使用 Keycloak 服務器驗證 JWT 令牌。因此,讓我們將其添加到我們的 pom 中:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

接下來,我們將向我們的 application.properties 添加 Keycloak 服務器的配置:

spring.security.oauth2.client.registration.keycloak.client-id=login-app
spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code
spring.security.oauth2.client.registration.keycloak.scope=openid
spring.security.oauth2.client.provider.keycloak.issuer-uri=
    http://localhost:8080/realms/SpringBootKeycloak
spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username

spring.security.oauth2.resourceserver.jwt.issuer-uri=http://localhost:8080/realms/SpringBootKeycloak

最後,我們將向我們的 UserController 添加一個檢索 User 的代碼:

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

2.2. 取消啓用 Keycloak

現在我們的應用程序已經就緒,我們來編寫一個簡單的測試來獲取用户:

@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());
}

此測試將失敗,因為我們沒有為 restTemplate 提供任何身份驗證,或者 Keycloak 服務器不可用。

Keycloak 適配器實現了 Spring 自動配置 的 Keycloak 安全功能。自動配置依賴於類在類路徑中存在或屬性值的存在。特別是,@ConditionalOnProperty 註解對於這種特定需求非常有用。

要禁用 Keycloak 安全功能,我們需要告知適配器不要加載相應的配置。我們可以通過如下方式設置屬性:

keycloak.enabled=false

如果在再次運行測試之前,我們再次運行測試,它將成功,而無需進行任何身份驗證。

3. 取消啓用 Keycloak 在 Spring Security 環境中的使用

我們經常將 Keycloak 與 Spring Security 結合使用。 在這種情況下,僅僅禁用 Keycloak 配置是不夠的,我們還需要修改 Spring Security 配置,以允許匿名請求到達控制器。

3.1. 應用程序設置

首先,我們向我們的項目添加 spring-boot-starter-security 依賴項:

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

接下來,我們創建一個 SecurityFilterChain bean,用於定義 Spring Security 所需的配置:

@Configuration
@EnableWebSecurity
public class KeycloakSecurityConfig {

    @Bean
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth.anyRequest()
                .permitAll())
            .oauth2Login(Customizer.withDefaults())
            .oauth2ResourceServer(httpSecurityOAuth2ResourceServerConfigurer -> 
                httpSecurityOAuth2ResourceServerConfigurer.jwt(Customizer.withDefaults()));
        return http.build();
    }
}

在這裏,我們配置 Spring Security 以僅允許來自經過身份驗證的用户請求。

3.2. 取消啓用 Keycloak

除了取消啓用 Keycloak 之外,我們現在還需要禁用 Spring Security。

我們可以使用 profiles 來告訴 Spring 是否應激活 Keycloak 配置,在我們的測試期間:

@Configuration
@EnableWebSecurity
@Profile("tests")
public class KeycloakSecurityConfig {
    // ...
}

但是,一種更優雅的方法是重用 keycloak.enable 屬性,類似於 Keycloak 適配器:

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

作為結果,Spring 僅在 keycloak.enable 屬性的值為 true 時才啓用 Keycloak 配置。 如果屬性丟失,matchIfMissing 將默認啓用它。

由於我們正在使用 Spring Security starter,僅僅禁用我們的 Spring Security 配置是不夠的。 事實上,遵循 Spring 的默認配置原則,starter 將創建一個默認的安全層。

讓我們創建一個配置類來禁用它:

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

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(request -> request.anyRequest()
                .permitAll());
        return http.build();
    }

}

我們仍然使用 keycloak.enable 屬性,但這次 Spring 僅在將其值設置為 false 時啓用配置。

4. 結論

在本文中,我們探討了如何在 Spring 環境中禁用 Keycloak 安全功能,無論是否使用 Spring Security。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.