Есть ли способ найти идентификатор поставщика OAuth2 из объекта ClientRegistration? - PullRequest
0 голосов
/ 24 апреля 2019

Я разрабатываю приложение, которое использует поддержку OAuth2 в Spring Security 5.x для входа в систему. Один из моих вариантов использования требует наличия нескольких клиентских регистраций для одного и того же провайдера идентификации OAuth2, а затем поиск идентификатора провайдера во время выполнения по объекту ClientRegistration, соответствующему клиенту OAuth2 в области применения. Существует ли публичный API, предоставляющий эту информацию?

API ClientRegistration: https://docs.spring.io/spring-security/site/docs/5.1.5.RELEASE/api/org/springframework/security/oauth2/client/registration/ClientRegistration.html не предоставляет эту информацию.

Я надеялся, что ProviderDetails: https://docs.spring.io/spring-security/site/docs/5.1.5.RELEASE/api/org/springframework/security/oauth2/client/registration/ClientRegistration.ProviderDetails.html включит его, но не повезло.

Я использую Spring Boot 2.x с конфигурацией YAML. Значение ключа provider в регистрационных данных клиента равно точно , что мне нужно для доступа во время выполнения:

spring:
  security:
    oauth2:
      provider:
        myprovider:
          authorization-uri: "https://oauth2.example.com/authorize"
          jwk-set-uri: "https://oauth2.example.com/jwks.json"
          token-uri: "https://oauth2.example.com/tokens"
      registration:
        client1:
          provider: "myprovider"
          client-id: "id-1"
          client-secret: "secret-1"
          authorization-grant-type: "authorization_code"
        client2:
          provider: "myprovider"
          client-id: "id-2"
          client-secret: "secret-2"
          authorization-grant-type: "authorization_code"

Это кажется странным упущением (и, очевидно, оно доступно для Spring Security внутри страны), поэтому я остаюсь почесывая голову и спрашиваю себя, упускаю ли я что-то очевидное.

Я предполагал, что смогу написать что-то вроде этого:

ClientRegistration registration = someObject.getClientRegistration();
String providerId = registration.getProviderId();

Но я не могу найти ничего эквивалентного #getProviderId() выше или даже ProviderRepository, аналогичного бобу ClientRegistrationRepository.

1 Ответ

1 голос
/ 24 апреля 2019

К сожалению, если вы посмотрите на автоконфигурацию Spring Boot, вы увидите, что эта информация никак не сохраняется.

Пояснение

Взятьпосмотрите на OAuth2ClientPropertiesRegistrationAdapter для логики создания ClientRegistration.

  1. Поставщик String для каждой регистрации регистрируется в поле OAuth2ClientProperties.Registration объекта, который был заполнен с использованием вашей конфигурации.
  2. Информация о поставщике, которую вы предоставляете в spring.security.oauth2.provider используется для создания OAuth2ClientProperties.Provider.Однако «providerId» не сохраняется в самом объекте (в любом случае он не имеет поля «providerId» или «providerName»).Вместо этого имя / идентификатор провайдера - это ключ к Map<String,Provider>, который существует в OAuth2ClientProperties.
  3. . При создании вашего ClientRegistration, провайдер String в вашем OAuth2ClientProperties.Registration используется для поискакарта.Когда провайдер найден, он используется для настройки ClientRegistration.Builder.

Это все, что получено из OAuth2ClientProperties.Provider:

private static Builder getBuilder(Builder builder, Provider provider) {
    PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
    map.from(provider::getAuthorizationUri).to(builder::authorizationUri);
    map.from(provider::getTokenUri).to(builder::tokenUri);
    map.from(provider::getUserInfoUri).to(builder::userInfoUri);
    map.from(provider::getUserInfoAuthenticationMethod)
        .as(AuthenticationMethod::new)
        .to(builder::userInfoAuthenticationMethod);
    map.from(provider::getJwkSetUri).to(builder::jwkSetUri);
    map.from(provider::getUserNameAttribute)
        .to(builder::userNameAttributeName);
    return builder;
}

Итак, "providerId"с OAuth2ClientProperties.Registration никогда не доходит до ClientRegistration, а "providerId" с OAuth2ClientProperties.Provider никогда не доходит до Provider.В итоге вы получите ClientRegistration с ProviderDetails ... но без "providerId" ...

...