{ Community }
  • Academy
  • Docs
  • Developers
  • Resources
    • Community Articles
    • Apigee on GitHub
    • Code Samples
    • Videos & eBooks
    • Accelerator Methodology
  • Support
  • Ask a Question
  • Spaces
    • Product Announcements
    • General
    • Edge/API Management
    • Developer Portal (Drupal-based)
    • Developer Portal (Integrated)
    • API Design
    • APIM on Istio
    • Extensions
    • Business of APIs
    • Academy/Certification
    • Adapter for Envoy
    • Analytics
    • Events
    • Hybrid
    • Integration (AWS, PCF, Etc.)
    • Microgateway
    • Monetization
    • Private Cloud Deployment
    • 日本語コミュニティ
    • Insights
    • IoT Apigee Link
    • BaaS/Usergrid
    • BaaS Transition/Migration
    • Apigee-127
    • New Customers
    • Topics
    • Questions
    • Articles
    • Ideas
    • Leaderboard
    • Badges
  • Log in
  • Sign up

Get answers, ideas, and support from the Apigee Community

  • Home /
  • General /
avatar image
1

Configuring Apigee to dispense OAuth tokens - either opaque or JWT  

  • Export to PDF
Dino-at-Google   created · Jan 27 at 01:54 AM · 94 Views · edited · Feb 01 at 05:16 PM

I had a question recently from someone who wanted to explore using Apigee to issue different kinds of OAuth tokens: either opaque tokens or JWT.

If you're not clear on the difference between Opaque tokens and JWT, then maybe read this first.

Apigee can generate either kind of token. Today, you need to use a distinct policy type, depending on the type of token you want to issue to the client.

  • for opaque tokens, use the OAuthV2 policy with Operation=GenerateAccessToken
  • for JWT, use the GenerateJWT policy

But it's not as simple as using either one policy or the other. I'll explain.

In the simple case, the request-for-token looks like this:

POST $tokenserver/token 
Content-Type: application/x-www-form-urlencoded
Authorization: Basic Zm9vOmJhcg==

grant_type=client_credentials

In other words, the client passes in credentials, as well as a form payload saying "this is a request for token for the grant_type of client_credentials".

In Apigee, the OAuthV2 policy with Operation=GenerateAccessToken will implicitly validate the client credentials provided in a Basic Auth header. The OAuth spec says "The authorization server MUST authenticate the client." and a good way to do that in Apigee is to use the OAuthV2 policy.

Normally the OAuthV2/GenerateAccessToken policy just generates the token response, and you're done. The flow looks like this:

    <Flow name='token1a'>
      <Description>token endpoint #1a</Description>
      <Condition>(proxy.pathsuffix MatchesPath "/token1a") and (request.verb = "POST")</Condition>
      <Request>
        <Step>
          <!-- Validation of the inbound request. Is the required form
               param present? -->
          <Condition>request.formparam.grant_type != "client_credentials"</Condition>
          <Name>RF-InvalidGrantType</Name>
        </Step>
      </Request>
      <Response>
        <Step>
          <!-- This policy implicitly validates the client credentials, and if
               valid, generates a token, and then generates a response
               containing that token, immediately. -->
          <Name>OAuthV2-GenerateAccessToken-CC</Name>
        </Step>
      </Response>
    </Flow>

Very simple!

The response payload looks something like this:

HTTP/1.1 200 OK
Date: Wed, 27 Jan 2021 01:13:31 GMT
Content-Type: application/json
Content-Length: 335
Connection: keep-alive
{
  "issued_at": 1611710011557,
  "client_id": "yzh0A4y6g9GsnR0MNIoAyiR17yXjVQnBF1eetkDAT9",
  "access_token": "lGU8R7nt5djo8VsnBa3GRZK99CGqAFkp8zkiu8Aw6MxGJPG1",
  "grant_type": "client_credentials",
  "expires_in": 1799,
  "issued": "2021-01-27T01:13:31.557Z",
  "expires_at": 1611711810557,
  "expires": "2021-01-27T01:43:30.557Z"
}

If you know anything about JWT, you can immediately recognize that the access_token in the above payload is not a JWT. It is not a dot-separated string, for one thing, and for another, it's not long enough. That is an opaque token. It can be validated only by Apigee.

OK, now what if you want to generate a JWT rather than an opaque token? In this case we use GenerateJWT, but... we also still need the OAuthV2/GenerateAccessToken. The reason is the requirement to authenticate the client. The OAuthV2 policy does that. It *also* generates a token, and for this use case, we don't need the token. But that's ok. With the OAuthV2/GenerateAccessToken, we accomplish our purpose of authenticating the client credentials.

After authenticating the client, we want Apigee to execute the GenerateJWT policy, and generate a signed JWT with the payload claims we need. And then "manually" embed that JWT into a response. The "flow" for this in Apigee looks like this:

    <Flow name='token2'>
      <Description>token endpoint #2</Description>
      <Condition>(proxy.pathsuffix MatchesPath "/token2") and (request.verb = "POST")</Condition>
      <Request>
        <Step>
          <!-- Validation of the inbound request. Is the required form
               param present? -->
          <Condition>request.formparam.grant_type != "client_credentials"</Condition>
          <Name>RF-InvalidGrantType</Name>
        </Step>
      </Request>
      <Response>
        <Step>
          <!-- This policy implicitly validates the client credentials, and if
               valid, generates a token, and then stores that token and other
               information about the token in a set of flow variables.
               We can then generate a JWT containing that information. -->
          <Name>OAuthV2-GenerateAccessToken-CC-NoResponse</Name>
        </Step>
        <Step>
          <Name>AM-SigningKeys</Name>
        </Step>
        <Step>
          <Name>GenerateJWT-RS256</Name>
        </Step>
        <Step>
          <Name>AM-Explicit-JWT-Response</Name>
        </Step>
      </Response>
    </Flow>

While the request for a JWT uses EXACTLY the same shape as a request for an opaque token, the response is different. It might look something like this:

HTTP/1.1 200 OK
Date: Wed, 27 Jan 2021 01:19:55 GMT
Content-Type: application/json
Content-Length: 846
Connection: keep-alive
{
  "access_token" : "eyJraWQiOiJyc2EtMjAyMTAxMjYtMTMxOCIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJvcGFxdWUtdG9rZW4iOiJtT2lybVM5RXY5RmxjOUcxbmoxbFI4YVgyTG1FNEw5S0ZhWjhNbnNKR1o5bGV1cGciLCJzdWIiOiJ5emgwQTR5Nmc5R3NuUjBNTklvQXlpUjE3eVhqVlFuQkYxZWV0a0RBVDkiLCJpc3MiOiJodHRwczpcL1wvZ2FjY2VsZXJhdGUzLXRlc3QuYXBpZ2VlLm5ldFwvb2F1dGgyLWNjLWFuZC1qd3RcL2Rpc3BlbnNhcnlcL3Rva2VuMiIsImV4cCI6MTYxMTcxMjE5NSwiaWF0IjoxNjExNzEwMzk1LCJqdGkiOiI0NGFlNjFmMC0xMzUyLTQyODgtYTI0MS1kNDEzOTUyOTAyM2EifQ.AG_y8bG7mFXzZEKBCLFXcZtPw3fL2P0zURG7tK9Vq6uynJ_Y86fOwWilDphyAhiqntq6TrqOFtTliMi2uKDW5QNr7C1BlPBoRvPtHz3AShpuovQzVpO4xTBCYE9rbugfxM-JkATJSJn39Ui5A9UrtLEzkcVhpS_xOdDVIn-bn1QEcI0-gspG5aFDqsHXtA9wFl1vbyRPTvh8aqm8-Rpo5ib4UBWvgOUKaTfI_a5uHINLFbVkP3zxzlx9zzIrCX_ehL7veEuvjLqplJMtUfff6yaHpmznxTMVXMM9EP9NIY6WMZLnlUgxEZUcbJSVdyFHbEFBOiPhLTHV5zNIsgEWeA",
  "token_type" : "Bearer"
}

Yes, a much longer token string there. That is a signed JWT. You can see the dots denoting the three distinct parts of the JWT. If you want to decode that particular JWT, you can click here.

----

If you want to try this yourself, I've got a GitHub repository with all the sample code, and a README to guide you along.

And finally, a Youtube screencast where I walk through this same information.

I hope this is helpful! Let me know if you have questions.

screenshot-20210126-180628.png (1.4 MB)
thub.nodes.view.add-new-comment
oauthjwtoauthv2client-credentialsoauth2.0
Add comment Show 1
10 |5000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by Apigeeks only
  • Viewable by the original poster
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Dino-at-Google ♦♦   · Jan 27 at 02:01 AM 0
Link

@sachin kalra FYI

Article

Contributors

avatar image

Follow this article

71 People are following this .

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Navigation

Configuring Apigee to dispense OAuth tokens - either opaque or JWT

Related Articles

Dispensing tokens via OAuthV2 with PKCE (RFC 7636)

POP - Using JWT to prove possession of a key

Screencast: Issuing OAuth tokens in Apigee Edge using Password Grant, and verifying same

How to store RSA keys for JWT into KVM? & retrieve them from within API Proxies?

Let's talk about JWT

Calling the Apigee Management APIs before and after enabling SSO

Enhancements coming soon in JWT Policies

Automating Access to the Apigee Management APIs using Machine User Credentials

Connecting to Salesforce APIs with Apigee using JWT auth. and mutual TLS

Introduction to JWT

  • Products
    • Edge - APIs
    • Insights - Big Data
    • Plans
  • Developers
    • Overview
    • Documentation
  • Resources
    • Overview
    • Blog
    • Apigee Institute
    • Academy
    • Documentation
  • Company
    • Overview
    • Press
    • Customers
    • Partners
    • Team
    • Events
    • Careers
    • Contact Us
  • Support
    • Support Overview
    • Documentation
    • Status
    • Edge Support Portal
    • Privacy Policy
    • Terms & Conditions
© 2021 Apigee Corp. All rights reserved. - Apigee Community Terms of Use - Powered by AnswerHub
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Create an article
  • Post an idea
  • Spaces
  • Product Announcements
  • General
  • Edge/API Management
  • Developer Portal (Drupal-based)
  • Developer Portal (Integrated)
  • API Design
  • APIM on Istio
  • Extensions
  • Business of APIs
  • Academy/Certification
  • Adapter for Envoy
  • Analytics
  • Events
  • Hybrid
  • Integration (AWS, PCF, Etc.)
  • Microgateway
  • Monetization
  • Private Cloud Deployment
  • 日本語コミュニティ
  • Insights
  • IoT Apigee Link
  • BaaS/Usergrid
  • BaaS Transition/Migration
  • Apigee-127
  • New Customers
  • Explore
  • Topics
  • Questions
  • Articles
  • Ideas
  • Badges