【问题标题】:OAuth2RestTemplate The access token provided has expiredOAuth2RestTemplate 提供的访问令牌已过期
【发布时间】:2016-04-10 21:17:48
【问题描述】:

我试图寻找解决方案很长时间,但没有发现任何有用的东西。 现在,直截了当。

我必须使用远程 OAuth2 身份验证服务器,并且我有使用它的凭据。身份验证用于 REST 服务调用。 REST 服务每隔 15 分钟被调用一次,我们的应用程序在一次迭代中调用了多个 URL。

第一次调用 REST API,一切正常,我们得到了访问令牌,它很有用。 1 小时后,当访问令牌过期并再次调用 REST API 时,我们收到以下错误:

The access token provided has expired

此错误有时会显示一次,有时会显示两次或更多。 再过 15 分钟 REST API 调用再次无错误。

我尝试使用属性retryBadAccessTokens,但没有运气。 我们正在使用 spring-security-oauth2-2.0.8.RELEASE 并进行以下设置:

<bean id="oipRestTemplate" class="org.springframework.security.oauth2.client.OAuth2RestTemplate" scope="prototype">
    <constructor-arg ref="oipClientCredentialsResourceDetail"/>
    <property name="accessTokenProvider" ref="tokenProvider"/>
    <property name="requestFactory" ref="httpComponentsClientHttpRequestFactory"/>
    <property name="retryBadAccessTokens" value="true"/>
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" >
                <property name="supportedMediaTypes">
                    <list>
                        <bean class="org.springframework.http.MediaType">
                            <constructor-arg value="application" />
                            <constructor-arg value="json" />
                        </bean>
                    </list>
                </property>
            </bean>
        </list>
    </property>
    <property name="errorHandler">
        <bean class="our.company.app.holders.MyResponseErrorHandler" />
    </property>
</bean>

【问题讨论】:

    标签: rest oauth-2.0 spring-security-oauth2


    【解决方案1】:

    看看他们是否也给你一个刷新令牌。您使用它们代表用户生成令牌。

    顺便说一句,如果你每 15 分钟打一次电话,我每次都会得到新的令牌。当您每分钟拨打数千个电话时,您不想这样做……但是 15 分钟?没什么大不了的。

    【讨论】:

    • 对 OAuth2Request 的响应:´{ "token_type": "Bearer", "access_token": "very_long_token", "expires_in": 1250 }´
    • 是的,您没有获得刷新令牌。就像我说的,如果你每 15 分钟打一次电话,那就换一个新的。相信我,这不会伤害服务器。
    • 现在好像没事了。在每次迭代开始时,我通过 oipRestTemplate.getOAuth2ClientContext().setAccessToken(null); 从 OAuth2ClientContext 中删除访问令牌
    【解决方案2】:

    我们有一个相当高的流量系统,我注意到我们遇到的故障总是在令牌即将到期的那一刻发生。 有没有可能是客户端看到token快要过期了,发给服务器,现在过期了,服务器拒绝了。

    如果是这种情况,我们需要一些缓冲空间,至少是 Oauth2RestTemplate 查看其令牌副本与服务器查看令牌之间的时间差。

    【讨论】:

    • 这如何回答这个问题?
    • 重点是Oauth2RestTemplate会自己自动刷新token。但是,它确实有一个小的失败窗口。如果它在令牌过期之前被调用,它将无法刷新它,并且它可能在它到达服务器时过期。我稍微修改了一下,以便它存储令牌的本地副本,并将过期时间缩短一分钟,从那以后我对过期令牌没有任何问题。
    【解决方案3】:

    我正在考虑向 Oauth2RestTemplate 本身发布一个 mod。

    if (accessToken == null || accessToken.isExpired())
    

    应该是

    if (accessToken == null || accessToken.isAboutToExpire())

    带有一些关于多早声明的配置值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      相关资源
      最近更新 更多