0

We are trying to authenticate to SalesForce Marketing Cloud through springboot security oauth2. By postman we can get an authorization token, but not from spring where we are receiving the error:

{
    "error": "invalid_request",
    "error_description": "Make sure that the client ID and client secret are valid and that the following parameters are not empty or null: client ID, client secret, and grant type.",
    "error_uri": "https://developer.salesforce.com/docs"
}

We could recreate the error in postman if we change the body request like this - see clientId:

{
 "grant_type": "client_credentials",
 "clientId": "{{SF_clientId}}",
 "client_secret": "{{SF_clientSecret}}",
 "account_id": "{{SF_accountId}}"
}

What we think that is happen is spring framework is adding clientId instead client_id in authorization request body.

We are using a FeignClient and this is our configuration class:

public class SalesForceConfiguration {

    @Value("${security.oauth2.salesforce.accessTokenUri}")
    protected String accessTokenUri;

    @Value("${security.oauth2.salesforce.clientId}")
    protected String clientId;

    @Value("${security.oauth2.salesforce.clientSecret}")
    protected String clientSecret;
    
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    @Bean
    ErrorDecoder errorDecoder() {return new SalesforceErrorDecoder();}

    @Bean
    RequestInterceptor oauth2FeignRequestInterceptor() {
        return new SalesforceAuthenticationFeignRequestInterceptor(oAuth2ClientContext(),
                oAuth2ProtectedResourceDetails(),
                null);
    }
    @Bean
    OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails() {
        final BaseOAuth2ProtectedResourceDetails resourceDetails = baseOAuth2ProtectedResourceDetails();
        resourceDetails.setAccessTokenUri(accessTokenUri);
        resourceDetails.setClientId(clientId);
        resourceDetails.setClientSecret(clientSecret);
        return resourceDetails;
    }

    private BaseOAuth2ProtectedResourceDetails baseOAuth2ProtectedResourceDetails() {
        return new ClientCredentialsResourceDetails();
    }

    OAuth2ClientContext oAuth2ClientContext() {
        return new DefaultOAuth2ClientContext();
    }
}

Does anyone already had the same problem and could share some advices?

Thanks!!!

1 Answer 1

2

Setting the authentication scheme to form seems to do the trick:

@Bean
OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails() {
  final BaseOAuth2ProtectedResourceDetails resourceDetails = baseOAuth2ProtectedResourceDetails();
  resourceDetails.setAccessTokenUri(accessTokenUri);
  resourceDetails.setClientId(clientId);
  resourceDetails.setClientSecret(clientSecret);
  resourceDetails.setClientAuthenticationScheme(AuthenticationScheme.form);
  return resourceDetails;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.