3rd party oauth - validation fails?

I'm working on creating a flow in which an oauth token is generated and (hopefully) registered with Edge, where it can be validated by Edge going forward.

I successfully generate the 3rd party token, and appear to correctly register the token with edge using the following GenerateAccessToken policy. This part is successful:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 name="GenerateAccessToken" continueOnError="false">
    <Operation>GenerateAccessToken</Operation>
    <ExpiresIn>1800000</ExpiresIn>
    <RefreshTokenExpiresIn>86400000</RefreshTokenExpiresIn>
    <RedirectUri>tokenexchange.redirect_uri</RedirectUri>
    <ExternalAccessToken>external-token</ExternalAccessToken>
    <ExternalAuthorization>false</ExternalAuthorization>
    <StoreToken>true</StoreToken>
    <SupportedGrantTypes>
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <GenerateResponse enabled="false"/>
    <ClientId>tokenexchange.requester</ClientId>
    <GrantType>authority.grant_type</GrantType>
</OAuthV2>

On subsequent calls, the token is placed in the Authorization header with a Bearer prefix. I use the following VerifyAccessToken policy to attempt to validate the token (and also hopefully capture app and developer analytics):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 async="false" continueOnError="false" enabled="true" name="Verify-OAuth">
    <DisplayName>Verify OAuth</DisplayName>
    <Operation>VerifyAccessToken</Operation>
</OAuthV2>

This fails.

I've tried with ExternalAuthorization set to true or false in one the other or both, as well as setting the oauth_external_authorization_status variable to true (when appropriate) ahead of the verification step. I've tried adding in the Client ID as a form param ... but I keep getting an invalid token message.

Based on the documentation at

http://docs.apigee.com/api-services/content/use-third-party-oauth-system

I don't see what else should be done.

Please advise.

0 11 397
11 REPLIES 11

@Paul Williams take a look here and how the service callout needs to be for the second part : https://community.apigee.com/questions/35483/validate-oauth-tokens-from-3rd-party-service.html

Hi @Christin Brown,

Actually the service callout is not the issue. The issue is that I can't figure out why Apigee Edge is not using internal validation to successfully register the analytics. In fact, the OAuth Verify Access Token step continually gives me an invalid access token response.

I've done this using BaaS to validate a users credentials and then use the BaaS provided token as the external token value.

First set the variables for the external OAuth policy using an Assign Message.

<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignExternalOAuthVariables">
    <DisplayName>AssignExternalOAuthVariables</DisplayName>
    <Properties/>
    <AssignVariable>
        <Name>oauth_external_authorization_status</Name>
        <Value>true</Value>
    </AssignVariable>
    <AssignVariable>
        <Name>grant_type</Name>
        <Value>client_credentials</Value>
    </AssignVariable>
    <AssignVariable>
        <Name>externalClientId</Name>
        <Ref>request.header.client_id</Ref>
    </AssignVariable>
    <Set>
        <FormParams>
            <FormParam name="client_id">{externalClientId}</FormParam>
        </FormParams>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

Then create the token

NOTE for some reason the client_id must be present as a form param even though I am referencing explicitly.

<OAuthV2 name="GenerateExternalAccessToken">
    <DisplayName>OAuth v2.0 1</DisplayName>
    <Operation>GenerateAccessToken</Operation>
    <ClientId>client_id</ClientId>
    <GrantType>grant_type</GrantType>
    <ExternalAccessToken>THIRDPARTY.access_token</ExternalAccessToken>
    <ExternalAuthorization>true</ExternalAuthorization>
    <ExpiresIn ref="THIRDPARTY.expiresIn">10</ExpiresIn>
    <ReuseRefreshToken>false</ReuseRefreshToken>
    <StoreToken>true</StoreToken>
    <SupportedGrantTypes>
        <GrantType>client_credentials</GrantType>
    </SupportedGrantTypes>
    <Tokens/>
</OAuthV2>

Once the token is created, I create a message and

<AssignMessage async="false" continueOnError="false" enabled="true" name="AssignExternalAuthorizationHeader">
    <DisplayName>AssignExternalAuthorizationHeader</DisplayName>
    <Properties/>
    <Set>
        <Headers>
            <Header name="Authorization">Bearer {externalAccessToken}</Header>
        </Headers>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

then invoke VerifyAccessToken policy.

<OAuthV2 async="false" continueOnError="true" enabled="true" name="VerifyAccessToken">
    <DisplayName>VerifyAccessToken</DisplayName>
    <Properties/>
    <Attributes/>
    <ExternalAuthorization>false</ExternalAuthorization>
    <Operation>VerifyAccessToken</Operation>
    <SupportedGrantTypes/>
    <Tokens/>
</OAuthV2> 

I did a quick demo of testing this in a single proxy. You will need to create your own client_id for the app and setup your own BaaS backend to test.

I did notice that I was getting an invalid client if I didn't use Form Param in the AssignExternalOAuthVariables policy, not sure why that is.

When this works, you will see a response like this:

{
    "appName": "ExternalAccessToken",
    "apiproductName": "ExternalAccessToken",
    "apiproxyName": "Demo-ExternalAccessToken",
    "externalClientId": "XXXORoXRSO6tPSPs0Rnfto5GKUnr9giZ",
    "externalAccessToken": "XXXtCPwbXXXEEeeYaOFxqwPThgAAAV6q24EACjw9pfKhRMkg62PYiiCHmoQ3OYk",
    "externalExpiryTime": "604"
}<br>

Bottom line, using this approach allows the external token (typically a JWT) to be used as the value in Edge.

The proxy is available in my Github repository here:

https://github.com/kurtkanaskie/Demo-ExternalAccessToken

Kurt, I'm still getting the invalid access token error:

{
    "fault": {
        "faultstring": "Invalid access token",
        "detail": {
            "errorcode": "oauth.v2.InvalidAccessToken"
        }
    }
}

You also have to set the secret sauce using Assign Message prior to creating the token

Yes, that is also being set correctly, and yet I continue to see failures.

Kurt, the server is denying me access to your zip file. Is there another place (e.g. github) where I can find the code?

Not applicable

Actually, my problem is same and I still stuck with this for 3 days 😞

@malina hugen did you look at the github repository where I shared the solution I described below? https://github.com/kurtkanaskie/Demo-ExternalAccessToken

Note that I converted your answer response to a comment.

Another data point is that with the help of @Sai Saran Vaidyanathan we proved that this flow works in some orgs, but not this one. We have raised a support request.

That's interesting.