Kotlin 配置

Spring Security Kotlin 配置自 Spring Security 5.3 版起已可用。它讓使用者可以使用原生 Kotlin DSL 配置 Spring Security。

Spring Security 提供了範例應用程式,示範如何使用 Spring Security Kotlin 配置。

HttpSecurity

Spring Security 如何知道我們想要要求所有使用者都必須通過身份驗證?Spring Security 如何知道我們想要支援表單式身份驗證?有一個配置類別 (稱為 SecurityFilterChain) 在幕後被調用。它使用以下預設實作進行配置

import org.springframework.security.config.annotation.web.invoke

@Bean
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
    http {
        authorizeHttpRequests {
            authorize(anyRequest, authenticated)
        }
        formLogin { }
        httpBasic { }
    }
    return http.build()
}
請務必匯入 org.springframework.security.config.annotation.web.invoke 函式,以在您的類別中啟用 Kotlin DSL,因為 IDE 並非總是自動匯入此方法,而導致編譯問題。

預設配置(如先前的列表所示)

  • 確保對我們應用程式的任何請求都要求使用者通過身份驗證

  • 允許使用者使用表單式登入進行身份驗證

  • 允許使用者使用 HTTP Basic 身份驗證進行身份驗證

請注意,此配置與 XML 命名空間配置平行

<http>
	<intercept-url pattern="/**" access="authenticated"/>
	<form-login />
	<http-basic />
</http>

多個 HttpSecurity 實例

我們可以配置多個 HttpSecurity 實例,就像我們可以有多個 <http> 區塊一樣。關鍵是註冊多個 SecurityFilterChain @Bean。以下範例針對以 /api/ 開頭的 URL 具有不同的配置

import org.springframework.security.config.annotation.web.invoke

@Configuration
@EnableWebSecurity
class MultiHttpSecurityConfig {
    @Bean                                                            (1)
    public fun userDetailsService(): UserDetailsService {
        val users: User.UserBuilder = User.withDefaultPasswordEncoder()
        val manager = InMemoryUserDetailsManager()
        manager.createUser(users.username("user").password("password").roles("USER").build())
        manager.createUser(users.username("admin").password("password").roles("USER","ADMIN").build())
        return manager
    }

    @Order(1)                                                        (2)
    @Bean
    open fun apiFilterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            securityMatcher("/api/**")                               (3)
            authorizeHttpRequests {
                authorize(anyRequest, hasRole("ADMIN"))
            }
            httpBasic { }
        }
        return http.build()
    }

    @Bean                                                            (4)
    open fun formLoginFilterChain(http: HttpSecurity): SecurityFilterChain {
        http {
            authorizeHttpRequests {
                authorize(anyRequest, authenticated)
            }
            formLogin { }
        }
        return http.build()
    }
}
1 照常配置身份驗證。
2 建立 SecurityFilterChain 的實例,其中包含 @Order 以指定應優先考慮哪個 SecurityFilterChain
3 http.securityMatcher 聲明此 HttpSecurity 僅適用於以 /api/ 開頭的 URL
4 建立另一個 SecurityFilterChain 的實例。如果 URL 不是以 /api/ 開頭,則使用此配置。由於此配置的 @Order 值在 1 之後(沒有 @Order 預設為最後),因此在 apiFilterChain 之後考慮此配置。