Edge generating the wrong OAuth2.0 token_type

Not applicable

It should really just return

"token_type": "Bearer",

instead of the current

"token_type": "BearerToken",

which is obviously wrong.

While developers *would* know that they need to use Bearer <token> in the Authorization header. it's just not pretty. And using API consoles like the one on SwaggerHub just fails as it reuses the token_type as the prefix to the token.

Solved Solved
1 17 2,730
1 ACCEPTED SOLUTION

Ohhh, It's just the name in the response. Totally understand.

You can change the response in the proxy using simple policies like JSON -> XML & then using policy like XSL Transformation to change the value to Bearer & Then back to JSON. Also, Extract Variables Policy & Assign Message to change the same to Bearer with out XSL Transformation policy.

Understand that OOB will be lot better & I will pass on the feedback to Engineering Team. You can also do that using Feedback button in new Edge UI left side bar.

When you actually send the token, You actually send Authorization header with prefix "Bearer <TOKENHERE>".

Hope it helps.

View solution in original post

17 REPLIES 17

@Ken Ng , Welcome to Apigee Community !

It's always "Bearer" in Apigee, See more details here. Any steps to reproduce issue that you see ?

I am not able to reproduce issue that you see. Any examples like proxy code, verify Access Token Policy & sample API will help to better understand same.

@Anil Sagar, I was referring to the payload that you get when generating the access token when using the

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<OAuthV2 name="GenerateAccessToken">
   <Operation>GenerateAccessToken</Operation>
   <ExpiresIn>3600000</ExpiresIn>
   <SupportedGrantTypes>
      <GrantType>client_credentials</GrantType>
   </SupportedGrantTypes>
   <GrantType>request.formparam.grant_type</GrantType>
   <GenerateResponse/>
</OAuthV2>

The following is then what's returned,

{
  "refresh_token_expires_in": "0",
  "api_product_list": "[Product]",
  "api_product_list_json": [
    "Product"
  ],
  "organization_name": "ken-ca2222228-trial",
  "developer.email": "ken@xxxxxxxx.com",
  "token_type": "BearerToken",
  "issued_at": "1505111115519",
  "client_id": "6eMmlXXXXXxXXXXXXXXXXLHhFk7",
  "access_token": "EqP3CCCCXXXXXXXXXZdLtZ8sd29",
  "application_name": "xxxxx8bd-xxxx-xxxx-xxxx-07exxxxx0e7",
  "scope": "",
  "expires_in": "3599",
  "refresh_count": "0",
  "status": "approved"
}<br>

Ohhh, It's just the name in the response. Totally understand.

You can change the response in the proxy using simple policies like JSON -> XML & then using policy like XSL Transformation to change the value to Bearer & Then back to JSON. Also, Extract Variables Policy & Assign Message to change the same to Bearer with out XSL Transformation policy.

Understand that OOB will be lot better & I will pass on the feedback to Engineering Team. You can also do that using Feedback button in new Edge UI left side bar.

When you actually send the token, You actually send Authorization header with prefix "Bearer <TOKENHERE>".

Hope it helps.

Is there any chance that this is on anyone's roadmap to fix? It's apparently been an issue since at least 2015, and breaks tools such as Swagger-UI. I understand that I can manually change the response, but not having to create a workaround for something like this would be very helpful. Thanks.

The reference number for this bug is b/115735130

It's in the backlog, but as you noted, it's been in the backlog for some time.

I'll see about making this small change.

For a service as large as Apigee, any incompatibility with the RFC is a serious bug. I know it's a bit dramatic to say this, but calling your implementation OAuth 2 when you have substantial known deviations (and have known about them for over 4 years) is claiming what isn't yours. You should be calling it OAuth 2-like rather than OAuth 2... or just fix the bugs!

That's fair!

Hi @Dino-at-Google, do you have an update about this bug? I also think apigee should be RFC compliant and understand why is not now or what is the reason for not being compliant?

Thanks!

working on it.

why is not now or what is the reason for not being compliant?

There's a bug. I don't know any other reason than that.

Hi @Ken Ng,

I've struggled with this in the past too with SwaggerHub and now with Apigee Spec Hub.

You can fix the response from the GenerateAccessToken to use token_type of "Bearer" as it should be, by using a simple JavaScript policy in the PostFlow after the OAuth policy. You can do this for all responses in the case where you may have multiple grant types with different policy names.

Here's the JavaScript code I used:

var obj = JSON.parse(response.content);
obj.token_type = "Bearer";
context.setVariable('response.content', JSON.stringify(obj));

Hope that helps.

Or else just set the GenerateResponse to false and build your own response using Assign Message policy or JS policy

Yes, however, then you have to go fishing for all the values and it will vary depending on the policy name, custom attributes, etc. This approach just lets everything go through as generated by the policy.

Agreed. But its a simple Assign Message policy

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-AccessToken-Response">
    <DisplayName>AM-AccessToken-Response</DisplayName>
    <Properties/>
    <Set>
        <Headers>
            <Header name="Content-Type">application/json</Header>
        </Headers>
        <Payload contentType="application/json" variablePrefix="@" variableSuffix="#">
            {
               "access_token":"@oauthv2accesstoken.OAuth2-Generate-AccessToken.access_token#",
               "refresh_token":"@oauthv2accesstoken.OAuth2-Generate-AccessToken.refresh_token#",
               "scope":"@oauthv2accesstoken.OAuth2-Generate-AccessToken.scope#",
               "expires_in":"@oauthv2accesstoken.OAuth2-Generate-AccessToken.expires_in#"
            }
        </Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="true" transport="http" type="response"/>
</AssignMessage>

where OAuth2-Generate-AccessToken is the name of the policy that generates the token

I did not have any luck w/the assign message policy. It does not bring over all the values sent in the payload such as token_type, just drops that attribute along w/others from looking at the trace:

9409-trace.png

Here's an Assign Message that I've used, note the name of my policy is "OA-GenerateAccessToken-Password" and I have set "GenerateResponse" to false.

<AssignMessage async="false" continueOnError="false" enabled="true" name="AM-GenerateAccessToken-Password">
    <DisplayName>AM-GenerateAccessToken-Password</DisplayName>
    <Set>
        <Headers/>
        <Payload contentType="application/json">
{
    "token_type": "Bearer",
    "organization_name": "{organization.name}",
    "externalUsername": "{externalUsername}",
    "externalAccessToken": "{externalAccessToken}",
    "api_product_list": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.api_product_list}",
    "api_product_list_json": [
        "{oauthv2accesstoken.OA-GenerateAccessToken-Password.api_product_list_json}"
    ],
    "developer.email": "{apigee.developer.email}",
    "issued_at": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.issued_at}",
    "client_id": "{apigee.client_id}",
    "access_token": "{apigee.access_token}",
    "application_name": "{apigee.developer.app.name}",
    "scope": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.scope}",
    "expires_in": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.expires_in}",
    "refresh_token_status": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.refresh_token_status}",
    "refresh_token_expires_in": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.refresh_token_expires_in}",
    "refresh_count": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.refresh_count}",
    "refresh_token": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.refresh_token}",
    "status": "{oauthv2accesstoken.OA-GenerateAccessToken-Password.status}"
}
</Payload>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

Note that the custom attributes I've set in the OA-GenerateAccessToken-Password policy are "externalUsername" and "externalAccessToken". They can be accessed with or without the oauth policy prefix.

The following seems to work fine?

<OAuthV2 async="false" continueOnError="false" enabled="true" name="Generate-Access-Token">
    <DisplayName>Generate Access Token</DisplayName>
    <FaultRules/>
    <Properties/>
    <Attributes>
        <Attribute name="token_type" display="true">Bearer</Attribute>
    </Attributes>
...

Adding an attribute just overrides the default one in the response.

I confirm this solution works fine and is the simpliest way of getting Apigee RFC compliant on this point.

Thank you !