springspring-securityoauth-2.0

Spring Method loadUser not called from custom OAuthUserService


I am trying to persist data about oauth logged users, but it seems that the method that I have overridden (loadUsers from DefaultOAuth2UserService) is not being called upon login completion. My code is as such:

@Service
public class OAuthUserService extends DefaultOAuth2UserService {
    private final UserRepository userRepository;

    public OAuthUserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2User oauth2User = super.loadUser(userRequest);
        Map<String, Object> attributes = oauth2User.getAttributes();
        String email = (String) attributes.get("email");
        String firstName = (String) attributes.get("given_name");
        String lastName = (String) attributes.get("family_name");
        String pictureUrl = (String) attributes.get("picture");
        String providerId = (String) attributes.get("sub");

        userRepository.findByEmail(email)
                .orElseGet(() -> {
                    User newUser = new User();
                    newUser.setEmail(email);
                    newUser.setFirstName(firstName);
                    newUser.setLastName(lastName);
                    newUser.setProfilePictureUrl(pictureUrl);
                    newUser.setProvider(AuthProvider.GOOGLE);
                    newUser.setProviderId(providerId);
                    newUser.setRole(UserRole.FREE);
                    return userRepository.save(newUser);
                });

        return oauth2User;
    }
}
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private OAuthUserService oAuthUserService; // Inject the service

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/", "/login**", "/error**", "/home").permitAll()
                        .anyRequest().authenticated()
                )
                .oauth2Login(oauth2 -> oauth2
                        .defaultSuccessUrl("/home", true)
                        .userInfoEndpoint(userInfo -> userInfo
                                .userService(oAuthUserService)
                        )
                );
        return http.build();
    }
}

Now after I login in using google oauth I can see JESSIONID, which I understand is the token received from google, so it seems the oauth exchanged completed successfully. However, I don't understand why my loadUser is not being called afterwards. (No data persisted in the db, I also placed break points in the loadUser method and they do not trigger + logs and nothing is printed)

I would appreciate some further guidance regarding this matter and thank you in advance if you are kind enough to offer some support


Solution

  • In app.yaml I have added openId for the scope of the oauth property. Because of this, instead of going with the oauth flow, Spring was triggering the open id connect flow. The solution was to extend the specific class of OidcService instead of DefaultOAuth2UserService