Send Docs Feedback

Note: Most user interface tasks can be performed in Edge Classic or the New Edge experience. For an overview, getting started topics, and release notes specific to the New Edge experience, see the docs.

Using third-party OAuth tokens

In this topic, we'll discuss how to store externally generated access tokens, refresh tokens, or auth codes as values in Edge-generated token or code metadata. This technique allows you to use the stored, third-party token value to make API proxy calls that can be validated by the Edge OAuth2 authentication service, just as if the token values were generated by Edge. 

If you want to see a working example that illustrates the technique described in this topic, take a look at the Apigee Delegated Token Management sample.

What is this?

Suppose you have an existing authorization system in place, and you would like to use the token or code values generated by that system in place of the OAuth2 token or code values that Edge generates. The technique described in this topic lets you store an externally generated token or auth code value in Edge-generated token or code metadata. You can then make secure API proxy requests with the substituted token or code, and Edge will validate them as if they were generated by Edge. 

For example, the metadata for an Edge-generated access token might look like the following, where the access_token attribute is a random string of letters and numbers generated by Edge. Remember that the value of the access_token attribute is essentially the "lookup key" for this metadata. When Edge receives a token in a request, it looks up this information and uses it to determine if the token is valid or not.

{
  "issued_at": "1469735625687",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "expires_in": "99",
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "zBC90HhCGmGlaMBWeZAai2s3za5j",
  "organization_name": "wwitman",
  "refresh_token_expires_in": "0",
  "refresh_count": "0"
}

On the other hand, by following the steps in this topic, you can generate a token so that its access_token value is the value of a token generated by an external authentication service. For example, the token might be 1234abcd as shown in this example:

{
  "issued_at": "1469735739602",
  "application_name": "06947a86-919e-4ca3-ac72-036723b18231",
  "scope": "",
  "status": "approved",
  "api_product_list": "[implicit-test]",
  "expires_in": "99",
  "developer.email": "joe@weathersample.com",
  "token_type": "BearerToken",
  "client_id": "U9AC66e9YFyI1yqaXgUF8H6b9wUN1TLk",
  "access_token": "1234abcd",
  "organization_name": "wwitman",
  "refresh_token_expires_in": "0",
  "refresh_count": "0"
}

In this case, you could make authenticated requests to Edge with the bearer token 1234abcd and Edge will be able to validate it. The same basic pattern applies to authorization codes and refresh tokens.

The key to using this technique is that at some point, before generating a token or auth code on Edge, you need to make a service callout to an external identity provider or authentication service. There are various ways to do this, but a Service Callout policy is commonly used. When you verify that you got back a valid token, you can then follow the steps described in this topic to generate a token (or auth code) in the Edge system that will use the third-party token value in place of the one that would have been generated by Edge. This way, you can make authenticated API proxy calls to Edge using the third-party token as if it were a token generated by the Edge OAuth2 authentication service itself. 

How to use third-party OAuth on Apigee

To use tokens from third-party OAuth systems in Apigee Edge, you need to do these things:

1. Configure the OAuthV2 policy

The OAuthV2 policy is the policy that you use to generate new access tokens, refresh tokens, and auth codes. Here's how you configure the policy to work with externally generated tokens or codes:

  • For the purpose of generating an access token, determine whether or not you want Edge to validate the required client credentials from its own authorization store or instead use credentials that will be recognized by the external authorization server. If you want to validate the Edge-stored credentials, set <ExternalAuthorization> element set to false. If you want to use the external authorization service to validate the credentials, set <ExternalAuthorization> to true. In the latter case, it is up to you to develop a policy flow where the externally recognized credentials are sent to the external auth service and, if valid, the returned access token is then used, as explained in the next bullet.
  • Configure one of these OAuthV2 elements: <ExternalAccessToken>, <ExternalRefreshToken>, or <ExternalAuthorizationCode>. These elements specify a flow variable where Edge should look to find the externally-generated access token, refresh token, or authorization code. It's up to you to implement policies/logic to call the external identity service, determine if the callout succeeded or not, and place the external token in the variable. For example, the following configuration tells Edge to look for the token in a request query parameter; however, it could be assigned to any flow variable accessible to the proxy.
<ExternalAccessToken>request.queryparam.external_access_token</ExternalAccessToken>
  • Set the <StoreToken> element in OAuthV2 to true.

2. Set the oauth_external_authorization_status flow variable to true

  • Before the OAuthV2 policy executes, you must set the flow variable oauth_external_authorization_status to true.

Typically, this variable is set to true or false based on a service callout to a third-party authorization service. You can look at the service callout response to determine of the callout succeeded or not and set the variable accordingly. Take a look at the ServiceCallout policy for details. A common technique for setting this variable is to use an AssignMessage policy with the AssignVariable element, like this:

<AssignMessage name="AssignMessage-SetVariable">
    <DisplayName>Assign Message - Set Variable</DisplayName>
    <AssignVariable>
        <Name>oauth_external_authorization_status</Name>
        <Value>true</Value>
    </AssignVariable>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

The following OAuthV2 policy generates an Apigee Edge access token given that Edge finds a token value in the flow variable request.queryparam.external_access_token. The location can be any variable, but in this case, it's the value of a query parameter:

<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>

Given the above configuration, you can request an access token as follows, where you pass in the value of the externally generated token in a query parameter. Again, how you obtain this value is beyond the scope of this topic. But a common technique would be to use Edge policies to parse the response from a service callout to the external auth service, and store the value of the returned token in a variable.

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

Important to note: Normally, with the client credentials grant type, you need to provide a Basic Authentication header with the encoded Client ID and Client Secret. However, in this case, you do not need to provide that header. Note that the client_id is still expected in the request and will be validated.  By default, Edge expects the client_id to be sent as x-www-form-urlencoded data.

In this case, Edge will generate an access token, with an access_token value of 123456. The token metadata might look something like this. And, as you can see, this token metadata has Apigee-specific properties that will enable it to work with developers, developer apps, and products registered on Edge.

{
  "issued_at" : "1415467907287",
  "application_name" : "9d3f4de-e501-4836-9bdd-f55e1d4b923",
  "scope" : "WRITE",
  "status" : "approved",
  "api_product_list" : "[PremiumWeatherAPI]",
  "expires_in" : "1799",
  "developer.email" : "tesla@weathersample.com",
  "organization_id" : "0",
  "token_type" : "BearerToken",
  "client_id" : "sxnS7Sdd6494Akb74ej4SmvvqjL0O",
  "access_token" : "123456"
  "organization_name" : "testmyapi",
  "refresh_token_expires_in" : "0",
  "refresh_count" : "0"
}

Finally, you might call an API like this, with 123456 as the OAuth2 bearer token:

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

In theory, you could apply this pattern with any third-party OAuth2 authorization service, like Google or Twitter.

Help or comments?