2
respostas

Authentication Manager retorna null

override fun attemptAuthentication(request: HttpServletRequest?, response: HttpServletResponse?): Authentication {
        val dadosAutenticacao: DadosAutenticacao = ObjectMapper().readValue(request?.inputStream, DadosAutenticacao::class.java)
        val token = UsernamePasswordAuthenticationToken(dadosAutenticacao.email, dadosAutenticacao.senha)
        val authentication: Authentication = authenticationManager?.authenticate(token) ?: throw RuntimeException("token não gerado...")
        return authentication
    }
    

no código do JWT o programa está reclamando da linha que está o val authentication que antes estava:

return  authenticationManager?.authenticate(token) ?: throw RuntimeException("token não gerado...")

ele cai na exception do token não gerado, após muito tempo, descobri que o authenticationManager está null, por isso cai na exception, a variavel token está recebendo certinho, porém o manager está null, inclusive quando injetei o authentication manager:

class JWTLoginFilter(@Autowired private val authenticationManager: AuthenticationManager?,
                     private val jwtUtil: JWTUtil
) : UsernamePasswordAuthenticationFilter() {

o debug/breakpoint/IntelliJ também fala que o authenticationManager está null. O que eu faço?

2 respostas

Descobri o erro, porém não sei como resolver :(

o authenticationManager do SecurityConfiguration no curso era do WebSecurityAdapter, mas agora que caiu em desuso, não sei qual authenticationManager usar, a linha em especifico é essa:

http.addFilterBefore(JWTLoginFilter(authenticationManager = , jwtUtil), UsernamePasswordAuthenticationFilter().javaClass
            )

e o SecurityConfig completo é esse:

package tjro.config.seguranca

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.invoke
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.core.userdetails.UserDetailsService
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import tjro.config.JWTUtil


@Configuration
@EnableWebSecurity
class SecurityConfiguration(
    private val userDetailsService: UserDetailsService,
    private val jwtUtil: JWTUtil
) {

    @Bean
    fun configure(http: HttpSecurity): SecurityFilterChain {

        http.invoke {
            csrf { disable() }
            authorizeRequests {
                authorize("/h2-console/**", permitAll)
                authorize("/login", permitAll)
                authorize("/usuarios/cadastro", permitAll)
                authorize("/usuarios/codigo-senha", permitAll)
                authorize("/usuarios/alterar-senha", permitAll)
                authorize(anyRequest, authenticated)
            }
            http.addFilterBefore(JWTLoginFilter(authenticationManager = , jwtUtil), UsernamePasswordAuthenticationFilter().javaClass
            )
            http.addFilterBefore(JWTAuthenticationFilter(jwtUtil), UsernamePasswordAuthenticationFilter().javaClass)
            sessionManagement {
                sessionCreationPolicy = SessionCreationPolicy.STATELESS
            }
            headers { frameOptions { disable() } }
            httpBasic { }
        }
        return http.build()
    }

    @Bean
    fun encoder(): PasswordEncoder {
        return BCryptPasswordEncoder()
    }

    @Bean
    @Throws(Exception::class)
    fun authenticationManager(authenticationConfiguration: AuthenticationConfiguration): AuthenticationManager? {
        return authenticationConfiguration.authenticationManager
    }

    fun configure(auth: AuthenticationManagerBuilder?) {
        auth?.userDetailsService(userDetailsService)?.passwordEncoder(BCryptPasswordEncoder())
    }

}

O problema que você está enfrentando é que a classe WebSecurityConfigurerAdapter foi descontinuada, e o método authenticationManager() foi removido dela. Agora, no Spring Security versão 5.x, o AuthenticationManager é obtido de forma diferente.

Para resolver o erro, você pode fazer algumas alterações no seu código:

  1. Remova o método authenticationManager(authenticationConfiguration: AuthenticationConfiguration): AuthenticationManager? e a anotação @Bean associada. Isso não é mais necessário.

  2. Modifique o método configure(auth: AuthenticationManagerBuilder?) para usar a classe UserDetailsService diretamente ao invés de obter o AuthenticationManager. Remova a chamada ao método passwordEncoder() nesse método também, pois você já está configurando o encoder no método encoder() que foi criado anteriormente.

Aqui está como ficaria o seu código ajustado:

@Configuration
@EnableWebSecurity
class SecurityConfiguration(
    private val userDetailsService: UserDetailsService,
    private val jwtUtil: JWTUtil
) {

    // ... outros métodos ...

    @Throws(Exception::class)
    fun configure(auth: AuthenticationManagerBuilder) {
        auth.userDetailsService(userDetailsService).passwordEncoder(encoder())
    }

    // ... outros métodos ...
}

Com essas alterações, o erro relacionado ao AuthenticationManager não deve mais ocorrer, e sua classe de configuração de segurança deve funcionar corretamente no Spring Security versão 5.x.

Certifique-se de que você está usando a versão apropriada das dependências do Spring Security em seu projeto para evitar possíveis problemas de compatibilidade.