Почему моя конфигурация oauth2 не использует мою пользовательскую службу UserService?

avatar
Maciej Kubiak
8 апреля 2018 в 08:06
2389
2
5

Я пытаюсь использовать аутентификацию Google. Я использую springboot2, поэтому большая часть конфигурации выполняется автоматически. Сама аутентификация работает хорошо, но потом я хотел бы заполнить Принципал своими данными (роли, имя пользователя и прочее).

Я создал MyUserService, расширяющий DefaultOauth2UserService, и пытаюсь использовать его следующим образом:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    MyUserService myUserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .oauth2Login()
                .userInfoEndpoint()
                    .userService(myUserService);
    }
}

Я проверил с помощью отладчика, что приложение фактически никогда не использует методы loadUser. А вот реализация MyUserService:

@Component
public class MyUserService extends DefaultOAuth2UserService {
    @Autowired
    UserRepository userRepository;

    public MyUserService(){
        LoggerFactory.getLogger(MyUserService.class).info("initializing user service");
    }

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {
        OAuth2User oAuth2User = super.loadUser(userRequest);
        Map<String, Object> attributes = oAuth2User.getAttributes();

        String emailFromGoogle = (String) attributes.get("email");
        User user = userRepository.findByEmail(emailFromGoogle);
        attributes.put("given_name", user.getFirstName());
        attributes.put("family_name", user.getLastName());

        Set<GrantedAuthority> authoritySet = new HashSet<>(oAuth2User.getAuthorities());

        return new DefaultOAuth2User(authoritySet, attributes, "sub");
    }
}
Источник

Ответы (2)

avatar
Maciej Kubiak
13 апреля 2018 в 20:25
9

На самом деле решение состояло в том, чтобы просто добавить еще одно свойство для проверки подлинности Google:

spring.security.oauth2.client.registration.google.scope=profile email

Не уверен, что такое область действия по умолчанию и почему вход в службу зависит от области действия, но без этой строки код никогда не попадал в мою пользовательскую службу.

Adrian Bob
18 ноября 2019 в 21:07
4

Ответ заключается в том, что по умолчанию, если вы не предоставляете какие-либо области при настройке клиента Google OAuth2, Spring Boot использует значения по умолчанию, предоставленные в классе CommonOAuth2Provider. И области по умолчанию: openid, профиль, электронная почта. При включении области openid Spring Boot будет использовать реализацию интерфейса OAuth2UserService OidcUserService, а не DefaultOAuth2UserService. Поэтому вы должны расширить OidcUserService. И настроить его

Jan-Willem Gmelig Meyling
23 октября 2021 в 15:44
0

Есть ли способ принудительно использовать OidcUserService вместо DefaultOAuth2UserService без добавления области openid?

avatar
TwiN
12 апреля 2018 в 21:34
3

Я думаю, вам не хватает аннотации @EnableOAuth2Client в начале вашего класса SecurityConfig.

Несмотря на это, я сделал пример с пользовательским сервисом для oauth2 здесь https://github.com/TwinProduction/spring-security-oauth2-client-example/, если это поможет

Maciej Kubiak
13 апреля 2018 в 20:16
1

Большое спасибо! Хотя это не было решением, ваш проект определенно помог мне решить эту проблему. Я напишу это в отдельном ответе, чтобы было легко найти, если кто-то наступит на ту же проблему.