External OAuth Token

Not applicable

We are being asked to support OAuth, in such a way that the client makes a call to OAuth application that will generate the token and provide it to the client, the client would then make calls to apigee with that token, so we'd be using third party tokens,

From the documentation, I see that the normal way of validating these 3rd party tokens would be using a service call out to an authorization and then setting the authorization status flow variable to true. My question is, is there any way to do that validation in apigee itself so there isn't a need to make a call out to an authorization server and then grant the client an apigee access token, essentially so we'd be able to let the client continue to use the OAuth application generated token?

The token itself would contain a client_id that is valid within apigee as well.

Thanks for any help.

Solved Solved
0 12 2,414
1 ACCEPTED SOLUTION

Not applicable

Hi @rj.walsh, I saw your comment on your previous post, but I'm still trying to understand what exactly your question is and why this question cannot be part of the initial thread. As a general recommendation, let's try to keep Apigee Community tight by keeping the questions under the same posts.

My suggestion to you is to try the example provided in my previous post, I think you'll find most of the answers to your questions. This tutorial shows that if you get the external token from a third-party, then Apigee OAuth Policy stores the token, and then validates it without hitting the the third-party OAuth resource. So, everything happens within Apigee.

This is a contrived example. However, it captures the essence of delegated authentication without getting into all the complexities of an implementation in a production environment.

1) From this call you can see that I set the token to whatever value I want:

curl https://testmyapi-test.apigee.net/oauth-delegated/generatetoken\?external_access_token\=123456 \
-d 'client_id=sxnS7SddD6494Akbqk74ej4SmvvqjL0O&grant_type=client_credentials' -v

2) Use the token set on the previous call:

curl https://testmyapi-test.apigee.net/oauth-delegated/music\?func\=getSong\&artist\=radiohead\&fmt\=json -H 'Authorization:Bearer 123456'

View solution in original post

12 REPLIES 12

if your oauth application can generate JWTs, then you could use it avoid service callouts in Apigee. You may be familiar with opaque OAuth access tokens, which need to be presented to the original issuer in order to be validated. Unlike those, JWTs can be used as independently-verifiable OAuth access tokens. Any parting in possession of a JWT can verify it, theoretically. A JWT is not opaque; it is encoded according to particular rules (base64, HMAC or RSA Signature, etc), and contains user information (claims). Any party can verify the signature to ensure a JWT is coming from the expected identity provider.

Thank you, I will look into this.

How will the JWTs avoid service callouts in Apigee? We would still need Apigee to make a service callout to retrieve & validate the JWT from the external IDP. Please let me know if I am missing something here?

JWT has the user info and the claims encoded in it, so there is no need to verify it with the IDP, it is intended for identity federation and letting service providers to authenticate and verify the claims without needing to go to IDP, [similar to saml]

http://jwt.io/ for more details,

Thanks Mukundha for the quick response. Since Apigee does not support JWT token validation out of the box. Do you suggest us to make a JAVA callout policy to perform claims validation?

yeah, its not oob -- but there are samples avaialble in the community, for eg, https://community.apigee.com/questions/9860/suppor...

I looked into the kjur jsrsasign utility associated with the example in the link. We have a requirement where the external IDP will sign the JWT using a private key. We will need to verify it using public key within Apigee.

kjur jsrsasign/Java callout needs to load public key string or public key itself from the Apigee keystore. Something like below:

pubKey = KEYUTIL.getKey(sRSAPUBKEY_X509CERT_PEM);

I checked there is no way to read the public key through management APIs. Is there a way to read public key string in Apigee?

Not applicable

Hi @rj.walsh, I saw your comment on your previous post, but I'm still trying to understand what exactly your question is and why this question cannot be part of the initial thread. As a general recommendation, let's try to keep Apigee Community tight by keeping the questions under the same posts.

My suggestion to you is to try the example provided in my previous post, I think you'll find most of the answers to your questions. This tutorial shows that if you get the external token from a third-party, then Apigee OAuth Policy stores the token, and then validates it without hitting the the third-party OAuth resource. So, everything happens within Apigee.

This is a contrived example. However, it captures the essence of delegated authentication without getting into all the complexities of an implementation in a production environment.

1) From this call you can see that I set the token to whatever value I want:

curl https://testmyapi-test.apigee.net/oauth-delegated/generatetoken\?external_access_token\=123456 \
-d 'client_id=sxnS7SddD6494Akbqk74ej4SmvvqjL0O&grant_type=client_credentials' -v

2) Use the token set on the previous call:

curl https://testmyapi-test.apigee.net/oauth-delegated/music\?func\=getSong\&artist\=radiohead\&fmt\=json -H 'Authorization:Bearer 123456'

Seems like this would work REALLY WELL. Simple and easy.

Just to elaborate on what @Dino is suggesting, the above example assumes that the third-party system has already generated an OAuth token. The first call in the above example, let's you provision the same third-party token in Apigee Edge for future reference and validation, whereas the second call is the actual call from the client with the access token requesting an api resource that is protected via OAuth2.0. The OAuth2.0 policy in this case would look like this:

<OAuthV2 name="OAuth-v20-Store-External-Token">
    <DisplayName>OAuth v2.0 1</DisplayName>
    <Attributes/>
    <ExternalAccessToken>request.queryparam.external_access_token</ExternalAccessToken>
    <ExternalAuthorization>true</ExternalAuthorization>
    <Operation>GenerateAccessToken</Operation>
    <GenerateResponse enabled="true">
        <Format>FORM_PARAM</Format>
    </GenerateResponse>
    <ReuseRefreshToken>false</ReuseRefreshToken>
    <StoreToken>true</StoreToken>
    <SupportedGrantTypes>
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <Tokens/>
</OAuthV2>

This just tells the apigee system, where to look for the external access token (request.queryparam.external_access_token) and whether to store the access token (StoreToken). When the first call is made, Apigee Edge would store the token in the datastore and associate it with the client-id so that when the actual request comes with the same access token requesting a protected resource, at that time Apigee can resolve the apikey/cliend-id from the token and resolve the apikey to resource mapping for the requested resource. I hope its clear now. You do not need to make any service callouts if you already have the access token that is generated by a third-party system.

@arghya das, @Dino, @Diego Zuluaga i am not sure if this is a good idea, the token is already generated by an external oauth provider, what would happen to scopes, expiry, authorization grants etc, and provider specific stuff [for eg, if we generate tokens - we use api products, resource mapping etc..], imho, we should either just rely on the provider [and may be cache the grants for lets say 1/10 of the expiry time] or fallback to federation, what do you guys think?

Thank you for your input, @Diego Zuluaga -- The solution I needed for that was just parsing a JWT that @Mukundha Madhavan referred to. From your answer, I got a better understanding of what is happening with 3rd party tokens and I am going to develop two APIs, one using JWT and one using the built in apigee system and determine which provides us with all the options we need.

Sorry for being dense and thanks for your help!