Как установить время ожидания соединения с OAuth2RestTemplate при получении токена доступа - PullRequest
0 голосов
/ 08 января 2019

Мы можем получить токен доступа, используя прикрепленный моментальный снимок кода, но не нашли способа установить время ожидания соединения, как мы делаем с пружиной restTemplate. Есть ли способ установить время ожидания соединения с OAuth2RestTemplate.

<bean id="bean" class="com.test.Provider">
            <constructor-arg name="context" ref="context" />
            <constructor-arg name="detail" ref="resourceDetails" />
        </bean>

        <bean id="context" class="org.springframework.security.oauth2.client.DefaultOAuth2ClientContext">
            <constructor-arg name="accessTokenRequest" ref="request" />
        </bean>

        <bean id="request" class="org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest"/>

        <bean id="resourceDetails" class="org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails"/>

1 Ответ

0 голосов
/ 15 июня 2019

Если я прав, то вы указываете тайм-аут подключения Spring RestTemplate в качестве аргумента конструктора, передавая ClientHttpRequestFactory в качестве аргумента конструктору

RestTemplate(ClientHttpRequestFactory requestFactory)

Используя, например, HttpComponentsClientHttpRequestFactory, можно установить тайм-аут подключения для RestClient в XML следующим образом

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
  <constructor-arg name="requestFactory">
    <bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
      <property name="connectTimeout" value="2000" />
      <property name="readTimeout" value="10000" />
    </bean>
  </constructor-arg>
</bean>

RestTemplate также предлагает способ установить свойство requestFactory через установщик, который он наследует от InterceptingHttpAccessor, и фактически сам конструктор, похоже, использует этот установщик для установки requestFactory, заданного в качестве аргумента конструктора.

Таким образом, вы можете установить requestFactory для OAuth2RestTemplate через установщик. В XML:

<bean id="oauth2RestTemplate" class="org.springframework.security.oauth2.client.OAuth2RestTemplate">
  <constructor-arg name="resource" ref="resourceDetails" />
  <constructor-arg name="context" ref="context" />
  <property name="requestFactory">
    <bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
      <property name="connectTimeout" value="2000" />
      <property name="readTimeout" value="10000" />
    </bean>
  </property>
</bean>

Или, в вашем случае, вы можете, например, дать вашему классу com.test.Provider аргумент конструктора requestFactory, а затем использовать его для установки фабрики запросов в OAuth2RestTemplate следующим образом:

XML:

<bean id="bean" class="com.test.Provider">
  <constructor-arg name="context" ref="context" />
  <constructor-arg name="resourceDetails" ref="resourceDetails" />
  <constructor-arg name="requestFactory">
    <bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
      <property name="connectTimeout" value="2000" />
      <property name="readTimeout" value="10000" />
    </bean>
  </constructor-arg>
</bean>

А в вашем кодовом наборе

OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(this.resourceDetails, this.context);
restTemplate.setRequestFactory(this.requestFactory);
String tokenString = restTemplate.getAccessToken().getValue();

после установки значения this.requestFactory в конструкторе.

PS. Я бы предпочел создать один OAuth2RestTemplate для всего класса в качестве частного поля и повторно использовать его в этом классе, если у вас нет причин создавать новый для каждого запроса. Вы можете создать его в конструкторе, так как вы предоставляете контекст и детали в качестве аргументов конструктора или затем в методе post-construct / init-method. Или даже передайте его как аргумент-конструктор или как свойство вашего класса в XML, если контекст и resourceDetails не используются вне restTemplate.

EDIT

После еще нескольких исследований кажется, что проблема может оказаться сложнее, чем я думал. OAuth2RestTemplate использует AccessTokenProvider для получения токенов доступа, по умолчанию он использует цепочку AccessTokenProviders через экземпляр AccessTokenProviderChain для поддержки различных типов типов предоставления. Кажется, что каждый из них использует свой собственный RestTemplate для отправки запросов на получение токена доступа. К сожалению, кажется, что OAuth2RestTemplate не предлагает простой способ установить requestFactory по умолчанию restTemplates AccessTokenProviders.

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

Все AccessTokenProviders по умолчанию в Spring Security Oauth2 расширяют класс OAuth2AccessTokenSupport, который также является классом, который создает внутренний RestTemplate. К счастью, этот класс предлагает установщик для установки requestFactory внутреннего RestTemplate. Таким образом, можно создать, например, экземпляр ClientCredentialsAccessTokenProvider и задать set requestFactory с помощью метода setRequestFactory (...). В XML:

<bean id="clientCredentialsAccessTokenProvider class="org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider">
  <property name="requestFactory">
    <bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
      <property name="connectTimeout" value="2000" />
      <property name="readTimeout" value="10000" />
    </bean>
  </property>
</bean>

По какой-то причине OAuth2RestTemplate не предлагает способ доступа к AccessTokenProviders по умолчанию, но их можно установить с помощью установщика setAccessTokenProvider (AccessTokenProvider accessTokenProvider). Чтобы воспроизвести исходное поведение OAuth2RestTemplate по умолчанию, нужно предоставить экземпляр AccessTokenProviderChain вместе с четырьмя AccessTokenProviders по умолчанию и установить их requestFactories. Однако, поскольку вы знаете, что доступ к ресурсу имеет тип ClientCredentialsResourceDetails, достаточно задать один ClientCredentialsAccessTokenProvider в сеттере setAccessTokenProvider (...) и установить requestFactory для ClientCredentialsAccessTokenProvider.

Итак, мы получили бы следующий код:

XML:

<bean id="bean" class="com.test.Provider">
  <constructor-arg name="context" ref="context" />
  <constructor-arg name="resourceDetails" ref="resourceDetails" />
  <constructor-arg name="accessTokenProvider" ref="clientCredentialsAccessTokenProvider" />
</bean>

<bean id="clientCredentialsAccessTokenProvider" class="org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsAccessTokenProvider">
  <property name="requestFactory">
    <bean id="requestFactory" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory">
      <property name="connectTimeout" value="2000" />
      <property name="readTimeout" value="10000" />
    </bean>
  </property>
</bean>

И в своем коде установите AccessTokenProvider:

OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(this.resourceDetails, this.context);
restTemplate.setAccessTokenProvider(this.accessTokenProvider);
String tokenString = restTemplate.getAccessToken().getValue();

после установки значения this.accessTokenProvider в конструкторе. Если вы решили создать OAuth2RestTemplate в XML, вы можете написать

<bean id="oauth2RestTemplate" class="org.springframework.security.oauth2.client.OAuth2RestTemplate">
  <constructor-arg name="resource" ref="resourceDetails" />
  <constructor-arg name="context" ref="context" />
  <property name="accessTokenProvider" ref="clientCredentialsAccessTokenProvider" />
</bean>

где bean-компонент "clientCredentialsAccessTokenProvider" определен, как указано выше.

Надеюсь, что это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...