Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

Use withCredentials in a Service Callout

I'm trying to invoke a URL from a Service Callout in Apigee. The URL is:

https://{{my-okta-org}}/api/v1/sessions/me

Which returns a JSON payload with the currently logged in user's session from Okta. When I call this from my API proxy in the browser, the Service Callout fails with a 404, because Okta can't resolve the session. But when you call the Okta URL directly from a browser, it works.

The reason (I think) is that the Okta Session cookie isn't being passed in the request from the Service Callout.

In JavaScript, you can fix this by using withCredentials, i.e.

 

const XHR = new XMLHttpRequest();
const url = "https://{{my-okta-org}}/api/v1/sessions/me"
XHR.open("GET", url);
XHR.withCredentials = true;
XHR.send();

 

Which instructs the browser to pass cross-domain cookies in the request.

But I can't figure out an alternative to withCredentials in an Apigee Service Callout.

I've thought about switching the whole thing into a JS policy, but the XMLHttpRequest or Fetch objects aren't available via the Apigee JS DOM, and the HttpClient object, which is available, doesn't seem to have withCredentials either.

Any suggestions?

1 2 416
2 REPLIES 2

.withCredentials in XHR... I believe is used for CORS requests from the browser. And yes, it will tell the XHR to propagate Authorization headers, cookies, and maybe TLS certs if you have them. 

If you are making a call to Okta from ServiceCallout, to implement the cookie-based authentication that the Okta sessions API, I believe you need to set the Cookie header.  To do that in ServiceCallout you can do something like this: 

 

<ServiceCallout name='SC-Okta-Session'>
  <Request variable='simpleGetRequest'>
    <Set>
      <Headers>
        <Header name='Cookie'>{cookie-value-here}</Header>
      </Headers>
      <Verb>GET</Verb>
    </Set>
  </Request>
  <Response>sessionResponse</Response>
  <HTTPTargetConnection>
    <SSLInfo>
      <Enabled>true</Enabled>
      <IgnoreValidationErrors>false</IgnoreValidationErrors>
    </SSLInfo>
    <URL>https://YOUR-OKTA-DOMAIN/api/v1/sessions/me</URL>
  </HTTPTargetConnection>
</ServiceCallout>

 

Where do you get the cookie?  I don't know - I suppose Okta will issue a cookie to the browser after an interactive login.  And so you will need to figure out how to propagate that Cookie from the browser into the Apigee API proxy in order to allow the session call to succeed.

I'm not sure how you'll do that. I believe the sessions API is intended for use from within browser-based web apps. 

It may be worth considering a different approach.  For example allow the client (web app?) to present the Okta-generated ID or access token to the API proxy.  Apigee can verify that the JWT was signed by Okta, is not expired, has the correct claims, etc. Then you may not need to invoke the sessions api. 

Thanks for the reply @dchiesa1 

I've got Okta authentication working through normal oAuth2 and OIDC. This particular Use Case was to carry over a legacy feature from an old API I am porting which synchronises the Okta session. It's not essential to the Auth flow, but helps minimise the grumbling when teams are told they need to port their API control to Apigee. I did tell them it was a bit of a long shot that I could get it working through Apigee.