[[kotlin-config]] = Kotlin Configuration Spring Security Kotlin configuration has been available since Spring Security 5.3. It lets users configure Spring Security by using a native Kotlin DSL. [NOTE] ==== Spring Security provides https://github.com/spring-projects/spring-security-samples/tree/main/servlet/spring-boot/kotlin/hello-security[a sample application] to demonstrate the use of Spring Security Kotlin Configuration. ==== [[kotlin-config-httpsecurity]] == HttpSecurity How does Spring Security know that we want to require all users to be authenticated? How does Spring Security know we want to support form-based authentication? There is a configuration class (called `SecurityFilterChain`) that is being invoked behind the scenes. It is configured with the following default implementation: ==== [source,kotlin] ---- @Bean open fun filterChain(http: HttpSecurity): SecurityFilterChain { http { authorizeRequests { authorize(anyRequest, authenticated) } formLogin { } httpBasic { } } return http.build() } ---- ==== The default configuration (shown in the preceding listing): * Ensures that any request to our application requires the user to be authenticated * Lets users authenticate with form-based login * Lets users authenticate with HTTP Basic authentication Note that this configuration is parallels the XML namespace configuration: ==== [source,xml] ---- ---- ==== == Multiple HttpSecurity Instances We can configure multiple HttpSecurity instances, just as we can have multiple `` blocks. The key is to register multiple `SecurityFilterChain` `@Bean`s. The following example has a different configuration for URL's that start with `/api/`: ==== [source,kotlin] ---- @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> authorizeRequests { authorize(anyRequest, hasRole("ADMIN")) } httpBasic { } } return http.build() } @Bean <4> open fun formLoginFilterChain(http: HttpSecurity): SecurityFilterChain { http { authorizeRequests { authorize(anyRequest, authenticated) } formLogin { } } return http.build() } } ---- <1> Configure Authentication as usual. <2> Create an instance of `SecurityFilterChain` that contains `@Order` to specify which `SecurityFilterChain` should be considered first. <3> The `http.antMatcher` states that this `HttpSecurity` is applicable only to URLs that start with `/api/` <4> Create another instance of `SecurityFilterChain`. If the URL does not start with `/api/`, this configuration is used. This configuration is considered after `apiFilterChain`, since it has an `@Order` value after `1` (no `@Order` defaults to last). ====