Сервер ресурсов Spring OAuth2 с сервером авторизации Google

Я пытаюсь реализовать простой сервер ресурсов Spring OAuth2, используя Google в качестве сервера OAuth.

По сути, я следил за такими руководствами, как этот spring-oauth2-with-google

приложение.yml:

      spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: *******.apps.googleusercontent.com
            client-secret:********_
            scope:
              - email
              - profile
              - openid
      resourceserver:
        jwt:
          issuer-uri: https://accounts.google.com
          jwk-set-uri: https://www.googleapis.com/oauth2/v3/certs

SecurityConfig.java:

      @Configuration
public class SecurityConfig {

    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .httpBasic().disable()
                .formLogin(AbstractHttpConfigurer::disable)
                .csrf(AbstractHttpConfigurer::disable)
                .authorizeRequests(authorize -> authorize
                                .anyRequest().authenticated()
                )
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .sessionManagement(sessionManagement ->
                        sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        ;
        return http.build();
    }
}

UserController.java

      @RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    @GetMapping("/{id}")
    public void getUser(@PathVariable String id) {
        System.out.println("Id: " + id);
    }
}

Я могу получить Google JWT через почтальона, как описано в руководстве, но как бы я ни старался, когда я пытаюсь использовать свою конечную точку через почтальона, ответ всегда 401. Я уже пытался установить пробел между ключевым словом Bearer и token_id.

Ошибка в почтальоне:

      Bearer error="invalid_token", error_description="Invalid token", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1"

но если я просмотрю токен в информации о токене Google, результат будет в порядке:

        "issued_to": "263667859573-jve8vplquh7qn4ft7aaj1t1m9boaq5d6.apps.googleusercontent.com",
  "audience": "263667859573-jve8vplquh7qn4ft7aaj1t1m9boaq5d6.apps.googleusercontent.com",
  "user_id": "112897290372529438679",
  "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "expires_in": 3296,
  "email": "javier@email.com",
  "verified_email": true,
  "access_type": "online"

1 ответ

Возможно, токен доступа, который вы получаете от Google, является просто не JWT, а непрозрачным токеном, и в этом случае настройка вашего сервера ресурсов с помощью декодера JWT не будет работать. попробуйте «открыть» один из ваших токенов доступа в таком инструменте, как https://jwt.io , чтобы быть уверенным.

Я не смог найти стандартную конечную точку самоанализа для таких непрозрачных токенов Google, просто https://www.googleapis.com/oauth2/v3/tokeninfo , на которую вы можете отправитькак параметр запроса. Если токен действителен, вы получите претензии в ответ. Таким образом, вы можете настроить свой ресурс-сервер с самоанализом токена (вместо декодера JWT), предоставив свой собственный интроспектор токена для вызова конечной точки tokeninfo, проверки ответа и либо выдачи исключения, либо возвратана ваш выбор.

              http.oauth2ResourceServer().opaqueToken().introspector(...);

Но это довольно сложная работа, и самоанализ гораздо менее эффективен, чем декодирование JWT (сначала требуется отправлять токен в Google для каждого входящего запроса на ваш ресурсный сервер, когда для второго достаточно получить открытый ключ только один раз для всех запросов).

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

Альтернативой для вас является использование другого сервера авторизации, способного объединять «социальные» удостоверения (конечно, Google, но также и Facebook, Github и т. д.). Многие делают это: Keycloak — известное локальное решение, но если вы не хотите самостоятельно поддерживать сервер авторизации, вы можете взглянуть на SaaS, например Auth0 (у которого есть бесплатный уровень). Эти два являются моими предпочтениями в настоящее время в галактике решений, просто найдите «сервер авторизации OIDC» и выберите свой собственный.

Другие вопросы по тегам