madorb 1ae99be1cf Clarify Package Import
Provide more explict instructions regarding the necessary import
to make the Kotlin DSL work. For some reason it took me 10 minutes
to figure this out based on the existing doc.
2024-04-30 08:48:57 -03:00

112 lines
4.0 KiB
Plaintext

[[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]
----
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()
}
----
[NOTE]
Make sure to import the `org.springframework.security.config.annotation.web.invoke` function to enable the Kotlin DSL in your class, as the IDE will not always auto-import the method, causing compilation issues.
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 parallels the XML namespace configuration:
[source,xml]
----
<http>
<intercept-url pattern="/**" access="authenticated"/>
<form-login />
<http-basic />
</http>
----
== Multiple HttpSecurity Instances
We can configure multiple `HttpSecurity` instances, just as we can have multiple `<http>` blocks.
The key is to register multiple `SecurityFilterChain` ``@Bean``s.
The following example has a different configuration for URLs that start with `/api/`:
[source,kotlin]
----
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> Configure Authentication as usual.
<2> Create an instance of `SecurityFilterChain` that contains `@Order` to specify which `SecurityFilterChain` should be considered first.
<3> The `http.securityMatcher` 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).