How to pass username and password in apigee to generate access token

I have an existing API which generates an access token and that access token would be usedwhile invoking other rest APIs, So how can i make use of apigee proxy to generate token by passing username and passwords in the rest api.

e.g :

Rest API : [centos@ank-vm ~]$ curl -X GET --header "Tenant: xyz" -u abc:def "http://180.148.27.101/api/v3.1/tokens"

Response :

{"role": "sys_admin", "value": "WyIyIiwiNDRiZjk5ODYwNGMzZjcwNjE3YzRjMDRlYWU4OTRkOTciXQ.DmG0ug.yPNEzNA9QSmADGlU4bRGzz5TSGY"}[centos@ank-vm ~]$ [centos@ank-vm ~]$

How can i generate the access token using apigee ?

Solved Solved
0 23 2,293
1 ACCEPTED SOLUTION

Hi @Ankit Goel, if you just want to pass info & call your STS to get token & then hit the target.

Use an Service Callout Policy. Here you can set the Headers to call the Tokens endpoint, get the token & the call your target endpoint.

<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1">
    <DisplayName>Custom label used in UI</DisplayName>
    <Request clearPayload="true" variable="myRequest">
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
       
        <Set>
            <Headers>
		<Header name="Tenant">xyz</Header>
	    <Headers/>
            <QueryParams/>
            <FormParams>        
		<FormParam name="username">abc</FormParam>   
	 	<FormParam name="password">xyz</FormParam>   
	    </FormParams>
            <Verb>GET</Verb>
        </Set>
    </Request>
    <Response>calloutResponse</Response>
    <Timeout>60000</Timeout>
    <HTTPTargetConnection>
        <URL>http://180.148.27.101/api/v3.1/tokens</URL>
        
    </HTTPTargetConnection>
    
</ServiceCallout>

Use Extract Variable policy to get the token,

<ExtractVariables name="ExtractVariables-3">
   <Source>calloutResponse</Source>
   <JSONPayload>
      <Variable name="token"">
         <JSONPath>$.value</JSONPath>
      </Variable>
   </JSONPayload>
   <VariablePrefix>oauth</VariablePrefix>
</ExtractVariables>

Then use an Assign Message Policy to set the extracted token as Header before hitting your target,

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="a_name">
    <DisplayName>a_display_name</DisplayName>
    <AssignTo createNew="false" transport="http" type="request"/>
    
    <Set>
       <Headers>
		<Header name="Authorization">{oauth.token}</Header>
       <Headers/>
       
    </Set>
    
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

View solution in original post

23 REPLIES 23

@Ankit Goel

Before generating the access token you need to understand what kind of Oauth grant-type is associated with the generate token functionality.

Like if it is Client_credentials then u need to pass the grant_type as client_credentials in query param or header along with base64 encoded username and password.

Thanks for you reply @Umanng . I am new to apigee . Just started learning it.. Can you please help me how can i add the client credentails as you mentioned and header as well



So Just want to know if the Create token api proxy is already available in Apigee, or you want to call the external service to generate the token.

I have an external rest api which when i call using curl or postman then it generate access token and that access token is used for further transactions, Below is the example of my external api .

curl -X GET --header "Tenant: xyz" -u username:password "http://180.148.27.101/api/v3.1/tokens"

Response :

{"role": "sys_admin", "value": "WyIyIiwiNDRiZjk5ODYwNGMzZjcwNjE3YzRjMDRlYWU4OTRkOTciXQ.DmG0ug.yPNEzNA9QSmADGlU4bRGzz5TSGY"}

It has generated the access token which i need to use for further transactions. So now i just want to invoke my external target api through apigee edge proxy.. And i just got stuck at point where i don't know how can i pass the header and credential information of my target api to apigee proxy . Just FYI i was trying with apigee UI. Your help would be really apprciated.

Hi @Ankit Goel, if you just want to pass info & call your STS to get token & then hit the target.

Use an Service Callout Policy. Here you can set the Headers to call the Tokens endpoint, get the token & the call your target endpoint.

<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1">
    <DisplayName>Custom label used in UI</DisplayName>
    <Request clearPayload="true" variable="myRequest">
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
       
        <Set>
            <Headers>
		<Header name="Tenant">xyz</Header>
	    <Headers/>
            <QueryParams/>
            <FormParams>        
		<FormParam name="username">abc</FormParam>   
	 	<FormParam name="password">xyz</FormParam>   
	    </FormParams>
            <Verb>GET</Verb>
        </Set>
    </Request>
    <Response>calloutResponse</Response>
    <Timeout>60000</Timeout>
    <HTTPTargetConnection>
        <URL>http://180.148.27.101/api/v3.1/tokens</URL>
        
    </HTTPTargetConnection>
    
</ServiceCallout>

Use Extract Variable policy to get the token,

<ExtractVariables name="ExtractVariables-3">
   <Source>calloutResponse</Source>
   <JSONPayload>
      <Variable name="token"">
         <JSONPath>$.value</JSONPath>
      </Variable>
   </JSONPayload>
   <VariablePrefix>oauth</VariablePrefix>
</ExtractVariables>

Then use an Assign Message Policy to set the extracted token as Header before hitting your target,

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="a_name">
    <DisplayName>a_display_name</DisplayName>
    <AssignTo createNew="false" transport="http" type="request"/>
    
    <Set>
       <Headers>
		<Header name="Authorization">{oauth.token}</Header>
       <Headers/>
       
    </Set>
    
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Thanks @Siddharth Barahalikar, I tried this what you said but in traces i could see it was failing with timeout error. even though i still increased the timeout.



Is this http://180.148.27.101/api/v3.1/tokens publically available? Check if Apigee access this URL?

Yes from this machine i can access apigee endpoints using curl

You can access Apigee endpoints because you are using Apigee Cloud account.

The token url may not be accesble on Internet, so you are getting timed out error. I mentioned the same thing in one of your other posts.

@Siddharth Barahalikar yes now i am able to generate the token . i opened the required port on firewall to make that ip accessible over internet and then it worked 🙂

But Now when i am trying to send Header "tenant" using service callout policy then it is failing.

<b><?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-1"> <DisplayName>Service Callout-1</DisplayName> <Properties/> <Request clearPayload="true" variable="myRequest"> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <Set> <Headers> <Header name="Tenant">ankit</Header> </Headers> <Verb>GET</Verb> </Set> </Request> <Response>calloutResponse</Response> <Timeout>60000</Timeout> <HTTPTargetConnection> <Properties/> <URL>http://<IP>/api/v3.1/blueprints?_include=id</URL> </HTTPTargetConnection> </ServiceCallout>

</b>

Error : {"fault":{"faultstring":"Execution of ServiceCallout Service-Callout-1 failed. Reason: ResponseCode 401 is treated as error","detail":{"errorcode":"steps.servicecallout.ExecutionFailed"}}}

In your curl cmd, you are also sending username & password as base64encoded string. Are you adding them in your Apigee proxy request?

Below is my curl command :

curl -X GET --header "Tenant: agoyal" -u username:password "http://180.148.27.101/api/v3.1/blueprints?_include=id"

Below is the flow:

1. I used key-map policy to set username and password

2. Then i used Basic authentication policy which will retrieve the username and passwords from KVM

3. Now i want to add header which is tenant:agoyal so for this i tried using assign message policy but it did not work and i tried service call out policy that also didn't work

Can you please downalod & upload your proxy bundle here for a quick solution?

You can mask or use dummy values for sensitive data.

cfy-list-blueprint-rev1-2018-08-31.zip

Please find attached proxy bundle

That's an invalid bundle I cant upload it,

Error uploading proxy: Bundle is invalid. Empty bundle.

Provide a valid bundle.

I just downloaded and made changes to sensitive info and it became invalid. Now i made changes to my running proxy and then downloaded. it should work now

cfy-list-blueprint-rev1-2018-08-31-1.zip

Why are you using mapIdentifier in Basic Auth policy? It is not required.

PFA Proxy. Try using it and change the mapIdentifier value n KVM policy.

no-target-13-rev2-2018-08-31.zip

Perfect. Thanks a lot @Siddharth Barahalikar. It worked now 🙂

Thank you so much

Regards,

Ankit Goel


Glad it worked. What about your other question? I think it is similar to this right?

Accept the answer, so that it helps others in future 🙂

yeah that same only.... and one more thing i saw i am getting the correct response in traces but when i hit the apigee url in browser it does not return the output. Do i need to add something ??

Yes sure i will accept the answer.

Tried the apigee url in postman also but here also body is empty while traces shows the body contents

Yes, after Service Callout you need to use an Assign Message policy to set the response of SC.

<AssignMessage name="set-dynamic-content">
  
  <Set>
    <Payload contentType="application/json">
      {calloutResponse.content}
    </Payload>
  </Set>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</AssignMessage>

Yup worked now 🙂 Thank you!!