Passing client_id and client_secret in Apigee X OAuth generate token policy as header

In Apigee X, is it possible to pass client_id and client_secret as header parameter  of the proxy. Read these values from proxy header and set in Generate token policy in the proxy flow. 

Solved Solved
0 11 301
1 ACCEPTED SOLUTION

In that case you can use single BasicAuthentication policy which will serve both the operation to create & assigning base 64 values to Authorization header

<User ref="request.header.X-CLIENT-KEY"/> 
<Password ref="request.header.X-CLIENT-SECRET"/>

 

View solution in original post

11 REPLIES 11

Can you elaborate on "is it possible to pass"?   Maybe clarify which link you're referring to. Add a subject and object there. Is it possible FOR WHAT to pass the header?

In a normal request-for-token, using client_credentials grant_type, the client passes the client_id and client_secret in a header, called Authorization, in an encoded form.  This is decribed in IETF RFC 6749, in section 4.4.  Is that what you're referring to? 

RFC_6749-sec4.4.2.png

We have followed this link : https://docs.apigee.com/api-platform/tutorials/secure-calls-your-api-through-oauth-20-client-credent...

Use case here is to pass client_id and client_secret in a proxy header as 2 separate headers. Extract these values and use in generate token policy for Oauth2.0 in the proxy flow with grant_type as client_credentials.

Adding more details to explain the use case:

  • Call API proxy 1 to generate an OAuth access token from client credentials. An OAuth v2.0 policy on the API proxy handles this.
  • Call API proxy 2 to send the OAuth access token in an API call. The API proxy verifies the access token using an OAuth v2.0 policy

    question is about API proxy 1 : To generate an OAuth access token  the below curl command is used
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" \
"https://ORG_NAME-test.apigee.net/oauth/client_credential/accesstoken?grant_type=client_credentials" \
-d "client_id=CLIENT_KEY&client_secret=CLIENT_SECRET"

Here, instead of sending client_id and client_secret as request body in x-www-form-urlencoded can we pass both the params as headers?

Yoc can't pass Client ID and Secret as direct headers. You have to encode it in the Basic Authorization header. As mentioned in the document 

You must pass the Client ID and Client Secret either as a Basic Authorization header (Base64-encoded) or as form parameters client_id and client_secret

You can refer the example from @dchiesa1  comment / doc here  

Yes, that's what documentation says. However, wanted to know if there is any direct or indirect way of consuming it from proxy header. Something similar found here:  which says:

Or, if necessary to support your client app base, you can mix and match headers and query parameters:

 
  ...
 
<GrantType>request.header.grant_type</GrantType>
  <Code>request.header.code</
Code>
 
<ClientId>request.queryparam.client_id</ClientId>
  <RedirectUri>request.queryparam.redirect_uri</
RedirectUri>
 
<Scope>request.queryparam.scope</Scope>
 
...

 

Yes, in Apigee X you can pass client_id and client_secret as proxy header parameters and use them in the token generation policy in your proxy stream.
To do this, you can create environment variables in your proxy that will extract the client_id and client_secret values from the request headers. These values can then be passed to the token generation policy in the proxy flow.

@JadielMiles  You are meant to say we have to use extract variable policy before the GenerateAccessToken policy, Something like below?

ExtractVariables

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="EV-GetRequestDetails">
    <DisplayName>EV-GetRequestDetails</DisplayName>
    <Properties/>
    <Header name="client_id">
        <Pattern ignoreCase="true">{request.formparam.client_id}</Pattern>
    </Header>
    <Header name="client_secret">
        <Pattern ignoreCase="true">{request.formparam.client_secret}</Pattern>
    </Header>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <Source clearPayload="false">request</Source>
</ExtractVariables>

GenerateAccessToken

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 name="GenerateAccessTokenClient">
    <!-- This policy generates an OAuth 2.0 access token using the client_credentials grant type -->
    <Operation>GenerateAccessToken</Operation>
    <!-- This is in millseconds, so expire in an hour -->
    <ExpiresIn>3600000</ExpiresIn>
    <SupportedGrantTypes>
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <GrantType>request.header.grant_type</GrantType>
    <GenerateResponse enabled="true"/>
</OAuthV2>

 

And triggering request like,

curl -X POST 'https://xxxxxxxxx.apigee.net/oauth/client_credential/accesstoken' \
-H 'client_id: xxxClientIDxxx' \
-H 'client_secret: xxxClinetSecretxxx' \
-H 'grant_type: client_credentials'

 

This actually works with assign message policy followed by adding a js policy to get base 64 encoded values. The outcome is then set as Authorizations header before verify policy is called.

Here is sample curl:

curl --location --request POST 'https://xxx/oauth-token-generation-api/accesstoken?grant_type=client_credentials' \
--header 'X-CLIENT-KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'X-CLIENT-SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

 

In that case you can use single BasicAuthentication policy which will serve both the operation to create & assigning base 64 values to Authorization header

<User ref="request.header.X-CLIENT-KEY"/> 
<Password ref="request.header.X-CLIENT-SECRET"/>

 

Its on the similar lines what @dchiesa1  suggested however adding the Authorization header is done in the pre flow after receiving client_id and client_secret as proxy header 

Thanks everyone for the insights shared. Have accepted the solution which worked for us.