Issue
I am new to Spring and Kotlin, and am trying to implement OAuth2 with a custom success handler. In the handler, I want to save the user details to my MongoDB database. Here is my security config (AuthenticationSuccessHandler is injected in the constructor):
@EnableWebSecurity
@Configuration
public class SecurityConfig(private val authenticationSuccessHandler : AuthenticationSuccessHandler) {
@Throws(Exception::class)
@Bean
public fun override(http: HttpSecurity): SecurityFilterChain {
return http
.csrf{csrf -> csrf.disable()}
.authorizeRequests{auth ->
auth.antMatchers("/api/brackets").authenticated()
auth.antMatchers("/**").permitAll()
}
.oauth2Login()
.successHandler(AuthenticationSuccessHandler())
.and()
.build()
}
}
and here is my AuthenticationSuccessHandler class (see autowired userRepository):
@Component
public class AuthenticationSuccessHandler : SavedRequestAwareAuthenticationSuccessHandler() {
private val redirectStrategy : RedirectStrategy = DefaultRedirectStrategy();
private val logger : Logger = LoggerFactory.getLogger(javaClass)
@Autowired
private lateinit var userRepository : UserRepository
@Throws(ServletException::class,IOException::class)
override public fun onAuthenticationSuccess(request : HttpServletRequest, response : HttpServletResponse, authentication : Authentication) {
//if redirected from some specific url, need to remove the cachedRequest to force use defaultTargetUrl
val requestCache : RequestCache = HttpSessionRequestCache();
val savedRequest : SavedRequest = requestCache.getRequest(request, response);
val userDetails : DefaultOidcUser = authentication.getPrincipal() as DefaultOidcUser
logger.info(userDetails.getIdToken().getTokenValue())
userRepository.save(User(userDetails.getName(), userDetails.getEmail(), AuthService.GOOGLE))
redirectStrategy.sendRedirect(request, response, "/api/testAuth");
}
}
Unfortunately when this handler is hit, the statement to save a new User fails with the message: "kotlin.UninitializedPropertyAccessException: lateinit property userRepository has not been initialized"
Any ideas why my userRepository is not being injected? Thank you so much!
Solution
It looks like the problem is that I wasn't using my injected instance of authenticationSuccessHandler and instead instantiating a new one without use of the spring framework. I was able to fix this by changing .successHandler(AuthenticationSuccessHandler())
to .successHandler(authenticationSuccessHandler)
that why the dependency injection worked
Answered By - Ethan Michel
Answer Checked By - Clifford M. (JavaFixing Volunteer)