How to obtain an oAuth token from apigee using an OKTA SAML assertion

Hi All,

I have a requirement where I need to authenticate users of my web application using OKTA's SAML flow.

Once the user is in the app will make some call to APIs proxied and secured via apigee using oAuth.

I need to be able to exchange my SAML assertion/token received from okta to receive a valid oAuth token from apigee for the user so that I can keep making calls to those services.

Does apigee provide such an API or capability for such an exchange. If not , is there another solution it offers to this problem?

Thanks,

Leo

Solved Solved
2 7 832
1 ACCEPTED SOLUTION

The OAuth2 framework specification (RFC 6749) describes some "standard" ways for clients to request tokens, and receive tokens.

Later, RFC 7522 augmented that spec by describing a way to exchange a SAML Assertion for an OAuth token.

SAML 2.0 Profile for OAuth 2.0 Client Auth Grants

RFC 7522 describes how a SAML Assertion can be used to request an access token when a client wishes to utilize an existing trust relationship, expressed through the semantics of the SAML Assertion, without a direct user approval step at the authorization server. It also defines how a SAML Assertion can be used as a client authentication mechanism.

and, a looong time ago Nandan produced an example showing how to implement this SAML-for-OAuth token exchange using Apigee. The example is available here. I suppose it still works.

View solution in original post

7 REPLIES 7

Not applicable

You can use SAML validation using service callout, once its validated you can forward the request to apigee to generate an oauth token.

Then you can use the oauth token for service request to verify and provide service response.

Thank you Priyadarshi Ajitav Jena for you response. Could you please elaborate a little bit:

  1. How do I validate the SAML using a service callout? Is there an apigee api for this?
  2. Do i need to pass some information from step number 1 of the validation into apigee to generate the oAuth token?

The OAuth2 framework specification (RFC 6749) describes some "standard" ways for clients to request tokens, and receive tokens.

Later, RFC 7522 augmented that spec by describing a way to exchange a SAML Assertion for an OAuth token.

SAML 2.0 Profile for OAuth 2.0 Client Auth Grants

RFC 7522 describes how a SAML Assertion can be used to request an access token when a client wishes to utilize an existing trust relationship, expressed through the semantics of the SAML Assertion, without a direct user approval step at the authorization server. It also defines how a SAML Assertion can be used as a client authentication mechanism.

and, a looong time ago Nandan produced an example showing how to implement this SAML-for-OAuth token exchange using Apigee. The example is available here. I suppose it still works.

Thank you very much Dino-at-Google for the reply , that is very helpful.

If I understood this example and RFC correctly , you simply pass the SAML assertion into the call to get the bearer token from apigee with the understanding that these two systems are in the circle of trust.

With that said, if I know the user id of a user, what prevents me from generating my own saml asserting , injecting the userid of someone else and asking for a bearer token?

In short how does apigee validate that this SAML request is indeed valid and coming from a legitimate source?

Thank you , leo.

It's a good question.

A SAML Assertion is signed by an identity provider using the private key known only by the identity provider (Okta or Azure AD or Google Signin, etc). The ValidateSAML policy in Apigee takes as configuration the TrustStore containing a certificate to verify the signature of on the SAML Assertion. Another way to say this: the ValidateSAML policy succeeds if and only if the signature on the saml assertion can be verified using a certificate that is _Trusted_.

So... if you produced a SAML Assertion and signed it with... your own private key, Apigee would reject it as untrusted. The signature on that assertion would not successfully verify using the public key belonging to the IDP. OTOH, if you somehow gained access to the private key that is used by the identity provider , then ... effectively you would be able to impersonate the identity provider. You would be able to sign assertions containing any claims you wanted, any email address, and Apigee (specifically the ValidateSAML policy) would trust those assertions, based on the valid signature. Obviously that would be bad. Protecting the keys used by an identity provider is really important.

All of that might not make a ton of sense if you don't have a background understanding of the principles of two distinct but related things:

  1. public/private key encryption (aka asymmetric cryptography)
  2. X.509 certificates

If you don't feel comfortable with those concepts, I encourage you to google around and read up on it. It will take some time to wade through it all, but it's fascinating computer science stuff, and also foundational. So good to know.

(continued below)

I'll try to provide a short summary. In the term "asymmetric cryptography", "asymmetric" refers to the fact that there are two dissimilar keys used, one for signing a thing, and another for verifying the signature. An analogy might be a lock that takes one key to lock, and another different key to unlock. These dissimilar keys are known as the private key and the public key. The former (private) is used for signing and the latter (public) for verifying. The private key is a secret possessed by exactly one party or actor, and it must not be shared. The public key is ...public and can be and often is shared widely. As an example, the address https://www.googleapis.com/oauth2/v3/certs provides the current list of public keys Google uses. Go ahead, click on it! You'll see a bunch of public keys (in JWK format).

A party like the IDP can sign something with its private key, and any other party (like Apigee) can verify the signature, using the public key of the IDP. Clear enough, right?

How can prospective verifiers be assured that the public key is the _right_ public key for a given party? If I had a public key that I thought belonged to Okta, but in fact was a false key generated by some malefactor, then I would trust signatures by the malefactor, as if they had been generated by Okta. No bueno.

There are several ways to address this challenge. X.509 is the most common. An x.509 Certificate, for our purposes, is a digital document that states that "THIS public key belongs to THIS particular party". If I trust that certificate, then ... I know the public key contained in the cert belongs to the asserted subject of the certificate. (the name of the IDP in this case). Therefore I can trust the public key.

The best path to trusting the certificate is to get the certificate directly from the IDP! If you can configure your SAML Relying party (as Apigee would be in this case) with the certificate that you KNOW is good, for example, by obtaining that cert directly from the IDP Administrative panels, then ... you can configure Apigee to trust that cert.

There is a twist. Certificates themselves are signed, and that means... if a verifier cannot get a cert _directly_ from the subject, then.... the verifier still might be able to trust the certificate if it verifies the signature on that certificate, and trusts the signer of that certificate. Verifying the signature on the certificate means... relying on another public key. You might call it "transitive trust". I might not directly trust Hannah, but if Bob vouches for Hannah, and I trust Bob, then I will trust Hannah. It's that sort of relationship.

This can produce a reliable "chain" of trust. I might not trust Hannah or Bob, but if I trust May, and May tells me she trusts Bob, and Bob tells me he trusts Hannah... then I can trust Hannah. The "chain" stops at a "root" trusted cert. Some foundational cert that the computer trusts implicitly. These usually belong to "root Certificate Authorities" like Entrust or Verisign or etc.

But this chain of trust is not REQUIRED. As I said, the best way for a party to trust a cert is to get it directly from the source. That's usually what is done by a SAML relying party.

OK, I said Certificates are a way to relate public keys to a particular subject.

Another way to relate public keys to particular owners is via ... a publicly-accessible well-known website. https://www.googleapis.com/oauth2/v3/certs is one such website. If you trust that the domain googleapis.com is owned and managed by Google, then you can trust that the public keys available there can be trusted. That means if I successfully verify a signature with one of those keys, then I can be assured that Google signed it.

If you're really savvy you'll notice that disseminating public keys via a website like this https://www.googleapis.com/oauth2/v3/certs ... relies on https, which itself relies on x.509 certificates. So the website "solution" for relating keys to an owner.... builds on the foundation of x.509 certificates. The X.509 Cert is really the basis on which website trust is built.

There are other ways to gain assurance that a particular public key corresponds to a particular party. But those two - certificates, and well-known website addresses that publish the keys - are the most common. SAML relies on certificates.

Most of this is "industry standard" stuff. SAML and X.509 and asymmetric crypto are standards that are used widely. None of this is particular to Apigee, EXCEPT for my comments above specifically about ValidateSAML, the policy in Apigee that does the verification of the SAML Assertion.

Thank you very much Dino-at-Google for the detailed response. I think understood most of it :). Leo