在 Spring Boot OAuth2RestOperations 中刷新 OAuth 令牌
Posted
技术标签:
【中文标题】在 Spring Boot OAuth2RestOperations 中刷新 OAuth 令牌【英文标题】:Refresh OAuth Token in Spring boot OAuth2RestOperations 【发布时间】:2020-02-17 03:03:44 【问题描述】:我正在使用 Spring Boot Cloud OAuth 客户端连接 Salesforce restapi。但是我收到Session expired or invalid
错误。无论如何刷新令牌我假设Spring Boot会在后台自动处理这个问题,但似乎情况并非如此。这是相关代码。
@Configuration
public class SalesforceConfiguration
@Value("$salesforce.tokenUrl")
private String tokenUrl;
@Value("$salesforce.clientId")
private String clientId;
@Value("$salesforce.clientSecret")
private String clientSecret;
@Value("$salesforce.username")
private String username;
@Value("$salesforce.password")
private String password;
@Bean
protected OAuth2ProtectedResourceDetails resource()
ResourceOwnerPasswordResourceDetails resource = new ResourceOwnerPasswordResourceDetails();
resource.setAccessTokenUri(tokenUrl);
resource.setClientId(clientId);
resource.setClientSecret(clientSecret);
resource.setClientAuthenticationScheme(AuthenticationScheme.form);
resource.setUsername(username);
resource.setPassword(password);
return resource;
@Bean
public OAuth2RestOperations restTemplate()
OAuth2RestTemplate operations = new OAuth2RestTemplate(resource(), new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
operations.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
operations.getMessageConverters().add(new StringHttpMessageConverter());
return operations;
这就是我在服务中使用它的方式。
@Component
public class QueryExecutor extends AbstractExecutor implements SalesforceExecutor
private OAuth2RestOperations restOperations;
public QueryExecutor(OAuth2RestOperations restOperations)
this.restOperations = restOperations;
@Override
public Response process(Request request) throws Exception
JsonNode jsonNode = restOperations.getForObject(buildUrl(request), JsonNode.class);
return new Response<>(ResponseCode.SUCCESS_GET.getCode(), jsonNode, request.getResponseHandler());
private String buildUrl(Request request)
return new StringBuilder().append(getServiceUrl(restOperations))
.append("/services/data/v41.0/query/?q=")
.append(request.getPayload().get("query"))
.toString();
如果我收到会话过期错误,是否可以使用这种方法无缝刷新令牌?
【问题讨论】:
【参考方案1】:好吧,经过几天的调试,我想我找到了这个问题的解决方案。这就是我能够解决它的方法。我将解决方案放在这里,以便其他人可以从中受益。
@Component
public class QueryExecutor implements SalesforceExecutor
private OAuth2RestOperations restOperations;
public QueryExecutor(OAuth2RestOperations restOperations)
this.restOperations = restOperations;
@Override
public Response process(Request request) throws Exception
try
JsonNode jsonNode = restOperations.getForObject(buildUrl(request), JsonNode.class);
return new Response<>(ResponseCode.SUCCESS_GET.getCode(), jsonNode, request.getResponseHandler());
catch (HttpClientErrorException | HttpServerErrorException e)
if (HttpStatus.UNAUTHORIZED.value() == e.getStatusCode().value())
restOperations.getOAuth2ClientContext().setAccessToken(this.getRenewedToken(restOperations.getResource()));
// retry again with renewed token
private String buildUrl(Request request)
return "someurl";
private OAuth2AccessToken getRenewedToken(OAuth2ProtectedResourceDetails resource)
OAuth2RestTemplate oAuth2RestTemplate = new OAuth2RestTemplate(resource, new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest()));
return oAuth2RestTemplate.getOAuth2ClientContext().getAccessToken();
就是这样。
【讨论】:
【参考方案2】:使用 Spring Boot,您应该不需要整个 SalesforceConfiguration
配置类。
您可以使用以下依赖项:
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>$look-for-the-latest</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-client</artifactId>
</dependency>
将配置属性添加到您的application.yml
:
security:
oauth2:
client:
username: the-username
password: the-password
client-id: the-client-id
client-secret: the-client-secret
grant-type: password,refresh_token
scope: read
access-token-uri: http://sales-force-domain/oauth/token
然后你可以像这样定义你的OAuth2RestTemplate
:
@Bean
public OAuth2RestTemplate oAuth2RestTemplate(final OAuth2ProtectedResourceDetails details)
return new OAuth2RestTemplate(details);
要使用它,只需按照您已经在做的方式,将OAuth2RestTemplate
注入QueryExecutor
。一旦您在application.yml
中将刷新令牌定义为grant-type
,Spring 就会处理刷新令牌。
In this repo,我有这个配置的工作版本,请耐心等待,因为它还演示了如何手动创建这个配置。
【讨论】:
谢谢,我会试试这个。但是是否会处理令牌刷新/会话超时? 这就是使用 Spring 的全部意义 :) 它确实会为您解决问题,只需正确设置即可。如果您确实将grant_type 设置为refresh_token
以及您需要的类型,它会成功
如果它对您有用,并且您可以将我的答案标记为正确答案,我将不胜感激。
遗憾的是,我收到了Unable to obtain a new access token for resource 'null'. The provider manager is not configured to support it.
,这是我以前没有收到的。
你能分享一些代码吗?公共回购将是最好的以上是关于在 Spring Boot OAuth2RestOperations 中刷新 OAuth 令牌的主要内容,如果未能解决你的问题,请参考以下文章
无法构建 Spring-boot-sample-gae(在 GAE 上部署 Spring Boot)
Spring Boot:管理的版本是 1.3.2.RELEASE 工件在 org.springframework.boot:spring-boot-dependencies:1.3.2.RELEASE
spring boot学习02如何在spring boot项目中访问jsp
如何在 spring-boot 中禁用 spring-data-mongodb 自动配置
Spring Boot 在使用 solrj 而不是 spring-boot-starter-data-solr 时会爆炸