在 Spring 引导 OAuth2RestOperations 中刷新 OAuth 令牌
Refresh OAuth Token in Spring boot OAuth2RestOperations
我正在使用 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();
}
}
如果出现会话过期错误,是否可以使用这种方法无缝刷新令牌?
使用 Spring 引导,您不需要整个 SalesforceConfiguration
配置 class。
您可以使用以下依赖项:
<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
。刷新令牌将由 Spring 处理,一旦您在 application.yml
.
中将其定义为 grant-type
In this repo,我有此配置的工作版本,请耐心等待,因为它还演示了如何手动创建此配置。
好吧,经过几天的调试,我想我终于找到了这个问题的解决方案。这就是我能够解决它的方式。我将解决方案放在这里,以便其他人可以从中受益。
@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();
}
}
就是这样。
我正在使用 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();
}
}
如果出现会话过期错误,是否可以使用这种方法无缝刷新令牌?
使用 Spring 引导,您不需要整个 SalesforceConfiguration
配置 class。
您可以使用以下依赖项:
<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
。刷新令牌将由 Spring 处理,一旦您在 application.yml
.
grant-type
In this repo,我有此配置的工作版本,请耐心等待,因为它还演示了如何手动创建此配置。
好吧,经过几天的调试,我想我终于找到了这个问题的解决方案。这就是我能够解决它的方式。我将解决方案放在这里,以便其他人可以从中受益。
@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();
}
}
就是这样。