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

Calling Google OAuth from Apigee X proxy (delegated authentication)

Hello all and @dchiesa1 ,
I am very new to apigee and I have been following this tutorial for delegated oauth authentication.

https://github.com/dzuluaga/apigee-tutorials/tree/master/apiproxies/musicapi-oauth-delegated-authent...
It uses the parameter ?external_access_token=123456 to the proxy to set the access token. 
My plan is using Google's Oauth to do the following:

1.  Call the https://accounts.google.com/o/oauth2/v2/auth to get the 'code' to exchange for a token.
2. Using the code from step 1, call https://www.googleapis.com/oauth2/v4/token with the code to get the real access token.
3. Extract the token and call the generatetoken endpoint with the parameter external_access_token={access token from google in step 2}

4. Call my OAuth protected proxy using the external access token from step 3

 

q1. Is this the correct way of using the Apigee and Google Oauth? I have seen a link about using extensions https://docs.apigee.com/api-platform/reference/extensions/google-authentication/google-authenticatio... but I am not seeing the connector callout policy anywhere. Is it the same as ServiceCallout? 

Here is my attempt to call google oauth

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
ServiceCallout async="false" continueOnError="false" enabled="true" name="Get-Access-Token">
<DisplayName>Get Access Token</DisplayName>
<Properties/>
<Request clearPayload="false" variable="myRequest">
<Set>
<Verb>POST</Verb>
<Headers>
<Header name="Content-Type">application/x-www-form-urlencoded</Header>
</Headers>
<FormParams>
<FormParam name="response_type">code</FormParam>
<FormParam name="client_id">...apps.googleusercontent.com</FormParam>
<FormParam name="scope">openid</FormParam>
<FormParam name="state">state_parameter_passthrough_value</FormParam>
<FormParam name="nonce">123456abcde}</FormParam>
<FormParam name="hd">company.com</FormParam>
<FormParam name="redirect_uri">https://www.googleapis.com/oauth2/v4/token</FormParam>
</FormParams>
</Set>
<IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
</Request>
<Response>calloutResponse</Response>
<HTTPTargetConnection>
<Properties/>
<URL>https://accounts.google.com/o/oauth2/v2/auth</URL>
</HTTPTargetConnection>
</ServiceCallout>

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables continueOnError="false" enabled="true" name="Extract-Variables-1">
<DisplayName>Extract Variables-1</DisplayName>
<Properties/>
<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
<JSONPayload>
<Variable name="expiresAt">
<JSONPath>$.code</JSONPath>
</Variable>
</JSONPayload>
<Source clearPayload="false">request</Source>
<VariablePrefix>apigee</VariablePrefix>
</ExtractVariables>

q2. Since I am planning to chain the auth and the token my redirect should be the token endpoint right? In apigee the policy flow should be service callout > extract variables > assign message (code) then do the same thing for token. Am I in the right track? Can someone please direct me to more examples of the extract variable/assign message policy? 

 

Thank you for your time!

Solved Solved
0 3 1,539
1 ACCEPTED SOLUTION

Great. I'm glad this discussion helped.

Absolutely, you can use Google Identity as a way to act as a "temporary" or "provisional" Identity provider for your users.  The token you obtain from Google Identity will be very similar to the tokens you get from Okta. You will be able to retain almost the identical policies in your Apigee APIs;  The VerifyJWT policy will change of course; it will use the JWKS URL for the Okta tenant, rather than the JWKS URL for the Google oauth service.  I guess  Okta offers a bit more depth in their IdP product (though I am not an expert on this), but Google Identity will satisfy this prototyping need, at the very least.  

In terms of learning Apigee X, would you still recommend referring to the 4 Minute Videos 4 Developers Playlist or would you consider that as outdated?

As regards 4MV4D, the videos that discuss and describe the individual policies, are still very good and relevant. All of the policies in Apigee Edge (As covered in those videos) also exist in Apigee X. The same policies, the same options, the same behavior, the same runtime. There are only a few exceptions.  So I do not consider the existing videos to be outdated. 

At the same time, the team is working on re-creating the videos with the current Apigee X product. That's a big effort, stay tuned for that.

View solution in original post

3 REPLIES 3

Hi, 

I think you're using Google's OpenID Connect endpoint to get an ID token and an Access Token.  Both of these are signed JWT.  That means that any party can verify the signatures on these tokens, and then make decisions based on the assertions (or claims) within those signed tokens. 

The ID token is intended for consumption by a third-party app, like maybe a website or a mobile phone app.  The app can use the ID token to determine the firstname, lastname, and email address, as authenticated by Google.  The app might want this to retrieve preferences, or a shopping cart, an order history, etc., specific to that authenticated user.

The access token is intended for consumption by a service.  The service can make an authorization decision based on the claims within the token, like sub, aud, and any others.

To configure Apigee to evaluate an access token, you can use the VerifyJWT policy.  You do not need to import the signed JWT as an external access token.  You could do that, but it's not necessary.  Let me explain 

When you use the OauthV2 policy in Apigee with Operation=GenerateAccessToken, normally Apigee generates a random, opaque string, and stores it into the persistent token store. According to the policy configuration Apigee can attach other attributes to that stored token, like an expiry, a scope, a grant type, and anything else you like. In the special case in which you use the OauthV2 policy in Apigee with Operation=GenerateAccessToken and the ExternalAccessToken element, then Apigee does not generate a random string, but stores the string you provide. In either case - with or without ExternalAccessToken - verifying the token is done with the OAuthV2 policy and Operation=VerifyAccessToken.  Apigee reads the token store, finds the unique string, and then retrieves all the other attributes. 

A signed token is distinct from an opaque token in that it requires no storage. While an opaque token is simply a string that is used as a lookup key (a way to find the claims associated to the token), a signed token has all the claims contained within it.  Because an opaque token is a lookup key, it needs to be only long enough to insure uniqueness and to defeat guessability. People use 43 or 48 characters. But because a  signed token contains encoded claims, it will generally be much longer than an opaque token - 512 bytes or much more. A signed token looks like a random string of characters, but in reality it's a concatenation of 3 base64-encoded values, none of which are random.  

Verifying a signed token just involves parsing the token and verifying the cryptographic signature. There's no I/O, there's no lookup. 

Therefore, it does not really make sense to "import" a signed token into the opaque token store in Apigee. You could do it, but there's probably a better way to do what you want. Either use the signed token directly, avoiding storage completely.... or, issue an opaque token in exchange for the signed token. 

I have seen a link about using extensions https://docs.apigee.com/api-platform/reference/extensions/google-authentication/google-authenticatio... but I am not seeing the connector callout policy anywhere.

I advise you to avoid the extensions. Those are not supported in the current version of Apigee. For current documentation, use URLs that begin with https://cloud.google.com/apigee/docs/; avoid the URLs beginning with docs.apigee.com.  

Since I am planning to chain the auth and the token my redirect should be the token endpoint right? In apigee the policy flow should be service callout > extract variables > assign message (code) then do the same thing for token. Am I in the right track?

There are two types of "transaction". The first is for token issuance. This can be a 3-legged flow as you described, where the user must authenticate, then the app needs to exchange a code for a signed token. The second type is for using the token, when the app requests some service. You can have the app present the token received during token issuance, and the receiver can verify the token before allowing service.

Apigee can perform the token validation in the second type of transaction, using VerifyJWT. Apigee need not participate in the token issuance. In other words, Apigee need not participate in the first type of transaction. You already have the endpoints for that (https://accounts.google.com/o/oauth2/v2/auth  etc), and your app can call them directly. No real need for Apigee there.

Per my understanding of the github repo you pointed to, the main reason you would include Apigee in the token issuance transaction is for indirection. To allow Apigee to delegate token issuance to one particular token issuer, among a set of token issuers.  This probably implies a set of distinct Identity Providers.  That seems like an advanced topic, and if you are unsure, you probably don't need it. even if you DO need it, I advise you to get the basic flow working: configure the app to get a token directly from your OIDC endpoint, and then send that signed token to Apigee. Let Apigee verify with VerifyJWT.

Why would you want multiple identity providers?  Suppose you were building a system for which existing accounts used the legacy, home-grown identity provider, and new accounts (created after, let's say July 1st, 2021), used the new identity provider, the Google accounts identity.  You might want Apigee to be able to make choices about which authentication endpoint to use. Or another example might be: people who connect from one set of countries might get identity provider A, while people who connected from a different set of countries could get identity provider B.  Those are the kinds of cases I can imagine where you'd want Apigee to mediate the first type of transaction - the token issuance. But if you don't have these kinds of requirements, then don't include Apigee in the token issuance flow. 

Maybe like this

cdraw.png

Thank you for the reply Dino, I truly appreciate your input! (and your videos) There is certainly a lot to cover and I did have some doubts on my original method and I am grateful for pointing me to the right direction. In the future we will be importing users and the plan is that only these users will be authorized to call our endpoints after being authenticated. 

Originally we had planned to use Okta as our identity provider and it made sense in a way that users registered in our Okta application will be authenticated to use our oauth protected endpoint.

I didn't really mean using multiple identity providers. My intention was to use Google Identity just a way to differentiate one authorized user from another since we're planning to implement role level security as well. 

In terms of learning Apigee X, would you still recommend referring to the 4 Minute Videos 4 Developers Playlist or would you consider that as outdated?

Great. I'm glad this discussion helped.

Absolutely, you can use Google Identity as a way to act as a "temporary" or "provisional" Identity provider for your users.  The token you obtain from Google Identity will be very similar to the tokens you get from Okta. You will be able to retain almost the identical policies in your Apigee APIs;  The VerifyJWT policy will change of course; it will use the JWKS URL for the Okta tenant, rather than the JWKS URL for the Google oauth service.  I guess  Okta offers a bit more depth in their IdP product (though I am not an expert on this), but Google Identity will satisfy this prototyping need, at the very least.  

In terms of learning Apigee X, would you still recommend referring to the 4 Minute Videos 4 Developers Playlist or would you consider that as outdated?

As regards 4MV4D, the videos that discuss and describe the individual policies, are still very good and relevant. All of the policies in Apigee Edge (As covered in those videos) also exist in Apigee X. The same policies, the same options, the same behavior, the same runtime. There are only a few exceptions.  So I do not consider the existing videos to be outdated. 

At the same time, the team is working on re-creating the videos with the current Apigee X product. That's a big effort, stay tuned for that.

Top Solution Authors