Outbound OAuth - Calling 3rd party oAuth secured services using client provided tokens

Not applicable

Hi,

I am trying to setup a proxy in Apigee that accepts client requests and calls Twitter search APIs.

The client sends consumer_key, consumer_secret, access_token_key & access_token_secret in its request to Apigee proxy. How do I make a backend request to Twitter with these tokens?

I am stuck while trying to build the header string as per the twitter documentation - https://developer.twitter.com/en/docs/basics/authentication/guides/authorizing-a-request

I have used "AssignMessage" policy to extract these tokens to build "Authorization" header string, but the "ServiceCallOut" policy has always been returing "215 Bad Authentication Data" from Twitter.

How do I percent encode these tokens within Apigee as per the twitter documentation on the link above?

Any suggestions on where I am off-track?

Thanks

0 5 383
5 REPLIES 5

HI @Prem Raghav

Welcome to the community !!

You will need to use a JavaScript policy instead of the Assign Message policy. You need to use the encodeURIComponent() function for each param and then assign it.

context.setVariable("oauth_signature", encodeURIComponent("tnnArxj06cWHq44gCs1OSKk/jLY="));

Please check and let us know if this works.

NOTE: Please trace the request you are sending and see if all the params are sent appropriately

@Sai Saran Vaidyanathan

Thanks for your valuable suggestion. I went ahead & implemented encodeURIComponent(). I now get a different error from Twitter - "{"errors":[{"code":32,"message":"Could not authenticate you."}]}. So Twitter does seem to notice some change from my earlier call.

Is this error because I am not using the SSL configuration properly? Here is the code snippet of my "Service CallOut" policy. I have used a "JavaScript" policy prior to the service callout to build the "head" variable as per twitter specs

<ServiceCallout name="Service-Callout-2" enabled="true" continueOnError="false" async="false">
    <DisplayName>Service Callout-2</DisplayName>
    <Properties/>
    <Request>
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
        <Set>
            <Headers>
                <Header name="Accept">*/*</Header>
                <Header name="Connection">close</Header>
                <Header name="User-Agent">OAuth gem v0.4.4</Header>
                <Header name="Content-Type">{contenttype}</Header>
                <Header name="Authorization">{head}</Header>
                <Header name="Content-Length">76</Header>
                <Header name="Host">{hosturl}</Header>
            </Headers>
            <QueryParams>
                <QueryParam name="q">{q}</QueryParam>
                <QueryParam name="count">{count}</QueryParam>
            </QueryParams>
            <FormParams/>
            <Verb>GET</Verb>
            <Path/>
        </Set>
    </Request>
    <Response>calloutResponse22</Response>
    <HTTPTargetConnection>
        <Properties/>
        <URL>https://api.twitter.com/1.1/search/tweets.json?q={q}</URL>
    </HTTPTargetConnection>
</ServiceCallout>

@Prem Raghav

I dont think you are passing the correct request to Twitter. As per their docs, they support OAuth2 client_credentials flow. If you have an app created, you should be able to generate an access token using their OAuth API and then use that token as Bearer to the Twitter API.

My recommendation to you would be to try calling Twitter APIs directly in your POSTMAN or any other REST client and see if it works. Once that works, you can build the proxy pointing to that