Skip to content

Instantly share code, notes, and snippets.

@monospacesoftware
Created November 7, 2020 15:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save monospacesoftware/07cfd9603442830d370024414a53f374 to your computer and use it in GitHub Desktop.
Save monospacesoftware/07cfd9603442830d370024414a53f374 to your computer and use it in GitHub Desktop.
How to use Spring Boot WebClient to access an OAuth2 password protected REST API
spring:
security:
oauth2:
client:
registration:
salesforce:
authorization-grant-type: password
client-authentication-method: post
client-id: <clientId>
client-secret: <clientSecret>
provider: salesforce
provider:
salesforce:
token-uri: https://foo.my.salesforce.com/services/oauth2/token
foo:
salesforce:
api-url: https://foo.my.salesforce.com/services/data/v49.0/sobjects/
api-user-name: <username>
api-password: <password>
package com.foo;
@Slf4j
@Service
public class SalesForceClient {
private final WebClient webClient;
public SalesForceService(@Qualifier("salesForceWebClient") WebClient webClient) {
this.webClient = webClient;
}
public String createCase(SalesForceCase salesForceCase) {
SalesForceResponse response = webClient.post()
.uri("/Case")
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(salesForceCase))
.retrieve()
.bodyToMono(SalesForceResponse.class)
.onErrorMap(e -> new SalesForceException("Error communicating with SalesForce API: " + e.getMessage(), e))
.block();
if (response == null)
throw new SalesForceException("No response from SalesForce API");
if (!response.isSuccess())
throw new SalesForceException("SalesForce API returned an error: " + Optional.ofNullable(response.getErrors()).map(List::toString).orElse("[]"));
return response.getId();
}
package com.foo.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.*;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import java.util.HashMap;
import java.util.Map;
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "foo.salesforce")
public class SalesForceConfig {
private String apiUrl;
private String apiUsername;
private String apiPassword;
@Bean
public OAuth2AuthorizedClientManager salesForceAuthorizedClientManager(ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientService authorizedClientService) {
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.password()
.build();
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
Map<String, Object> passwordAttributes = new HashMap<>();
passwordAttributes.put(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, getApiUsername());
passwordAttributes.put(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, getApiPassword());
authorizedClientManager.setContextAttributesMapper(request -> passwordAttributes);
return authorizedClientManager;
}
@Bean
public WebClient salesForceWebClient(@Qualifier("salesForceAuthorizedClientManager") OAuth2AuthorizedClientManager authorizedClientManager) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oAuth2Filer = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oAuth2Filer.setDefaultClientRegistrationId("salesforce");
return WebClient.builder()
.filter(oAuth2Filer)
.baseUrl(getApiUrl())
.build();
}
}
@rafonsecad
Copy link

rafonsecad commented Aug 5, 2023

@monospacesoftware thanks for sharing, one thing to notice though, since spring security 5.5 the values for client-authentication-method changed, so instead of post we need to replace it by client_secret_post. I just ran into this issue updating spring boot, here we can see the commit and post value was removed here for version 6.0.0

@larsf96 @maksymgendin check this out.

@maksymgendin
Copy link

@monospacesoftware thanks for sharing, one thing to notice though, since spring security 5.5 the values for client-authentication-method changed, so instead of post we need to replace it by client_secret_post. I just ran into this issue updating spring boot, here we can see the commit and post value was removed here for version 6.0.0

@larsf96 @maksymgendin check this out.

Yeah, you're right, the values have changed. Thanks for notifying.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment