You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.9 KiB
111 lines
3.9 KiB
|
|
[[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 `invoke` function 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).
|
|
|