I am writing application in spring boot
2.7.4
version which has new version of spring security
. So I need to rewrite my old code to the new one.
Here is my old security configuration with WebSecurityConfigurerAdapter
@Configuration
@EnableWebSecurity
class AppWebConfig(
val customUserDetailsService: CustomUserDetailsService,
val passwordEncoder: PasswordEncoder,
val tokensService: TokensService
) : WebSecurityConfigurerAdapter() {
@Throws(Exception::class)
override fun configure(auth: AuthenticationManagerBuilder) {
auth
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder)
}
@Throws(Exception::class)
override fun configure(http: HttpSecurity) {
http
.cors()
.and()
.csrf().disable()
.exceptionHandling()
//urls permissions...
.addFilter(AppAuthorizationFilter(authenticationManager(), tokensServicee))
}
}
And here is the new code
@Configuration
@EnableWebSecurity
class AppWebConfig(
val tokensService: TokensService,
) {
@Bean
@Throws(Exception::class)
fun authenticationManager(authenticationConfiguration: AuthenticationConfiguration): AuthenticationManager? {
return authenticationConfiguration.authenticationManager
}
@Bean
@Throws(Exception::class)
protected fun fitlerChain(http: HttpSecurity): SecurityFilterChain {
val authenticationManager = http.getSharedObject(AuthenticationManager::class.java)
return http
.cors()
.and()
.csrf().disable()
//urls permissions...
.addFilter(AppAuthorizationFilter(authenticationManager, tokensService))
.build()
}
Here is the AppAuthorizationFilter
which hasn't changed in both versions and where the authenticationManager
is used:
class AppAuthorizationFilter(
authenticationManager: AuthenticationManager,
tokensService: TokensService,
) : BasicAuthenticationFilter(authenticationManager) {
private val tokensService: TokensService
init { this.tokensService = tokensService }
@Throws(IOException::class, ServletException::class)
override fun doFilterInternal(
request: HttpServletRequest,
response: HttpServletResponse,
chain: FilterChain,
) {
val header = request.getHeader(Objects.requireNonNull(HttpHeaders.AUTHORIZATION))
if (header != null) {
val authorizedUser = tokensService.parseAccessToken(header)
SecurityContextHolder.getContext().authentication = authorizedUser
}
chain.doFilter(request, response)
}
}
And the problem is with authenticationManager
from AppWebConfig
. I get the error that this its null.
Caused by: java.lang.NullPointerException: authenticationManager must not be null at com.app.security.config.WebConfig.fitlerChain(WebConfig.kt:68)
I tried the solution I showed above by getting authenticationManager
from shared objects http.getSharedObject(AuthenticationManager::class.java)
but it does not work as you can see.
I solved the problem by getting authenticationManager
from WebApplicationContext
but I am not sure if it is the best way to do it
val authenticationManager = applicationContext.getBean("authenticationManager") as AuthenticationManager
Try to add this annotation (@Primary)
to you authenticationManager bean. If didn't work, then go with the solution you mentioned.
@Bean
@Primary // try to add this
@Throws(Exception::class)
fun authenticationManager(authenticationConfiguration: AuthenticationConfiguration): AuthenticationManager? {
return authenticationConfiguration.authenticationManager
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With