-
-
Save monospacesoftware/07cfd9603442830d370024414a53f374 to your computer and use it in GitHub Desktop.
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(); | |
} | |
} |
Hello,
It's saving my time but still i couldn't understand some of the class integrations .. can you please help me on this
where exactly store the token and how we are using that token in next requests.
if i run my spring application...
Always i got Login with OAuth 2.0 this message
Hello, It's saving my time but still i couldn't understand some of the class integrations .. can you please help me on this where exactly store the token and how we are using that token in next requests.
if i run my spring application... Always i got Login with OAuth 2.0 this message
The "Login to OAuth" is coming because the service you created is also getting protected by OAUTH.
Refer to post: https://fullstackdeveloper.guru/2022/03/17/how-to-invoke-oauth2-protected-microservice-using-webclient-in-spring-boot/
Above states to use WebSecurityConfigurerAdapter to address this issue. However this is now deprecated. So can use SecurityFilterChain instead
https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
Just in case someone is looking for a reactive way 🙂
@Bean
@Qualifier(CLIENT_NAME)
ReactiveOAuth2AuthorizedClientManager authorizedClientManager(ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService) {
final ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.password()
.build();
final AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
authorizedClientManager.setContextAttributesMapper(request -> Mono.just(Map.of(
OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME, getUsername(),
OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME, getPassword()
)));
return authorizedClientManager;
}
@Bean
@Qualifier(CLIENT_NAME)
WebClient webClient(@Qualifier(CLIENT_NAME) ReactiveOAuth2AuthorizedClientManager clientManager) {
final ServerOAuth2AuthorizedClientExchangeFilterFunction filter =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientManager);
filter.setDefaultClientRegistrationId(CLIENT_NAME);
return WebClient.builder()
.filter(filter)
.baseUrl(getBaseUrl())
.build();
}
@shone1991 This is probably the solution for your case 😬
I'm still getting org.springframework.security.oauth2.core.OAuth2AuthorizationException: [invalid_client_id] client identifier invalid
even if I use the same credentials as in Postman.
@pabbott-ANet Did you figure out how to solve that?
I'm still getting org.springframework.security.oauth2.core.OAuth2AuthorizationException: [invalid_client_id] client identifier invalid even if I use the same credentials as in Postman. @pabbott-ANet Did you figure out how to solve that?
Check authorization-grant-type
and client-authentication-method
in your provider configuration, if you're not using a predefined one.
@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.
@monospacesoftware thanks for sharing, one thing to notice though, since spring security 5.5 the values for
client-authentication-method
changed, so instead ofpost
we need to replace it byclient_secret_post
. I just ran into this issue updating spring boot, here we can see the commit andpost
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.
when I run the app it keeps saying
Parameter 0 of method salesForceAuthorizedClientManager in dev.egov.oauth2client.config.WebClientConfig required a bean of type 'org.springframework.security.oauth2.client.registration.ClientRegistrationRepository' that could not be found.