{ 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 /
  • Edge/API Management /
avatar image
2
Question by Tuomas Suni · Sep 05, 2018 at 07:09 PM · 348 Views oauth 2.0authenticationaccess tokenexternal authenticationclient_credentials

Single API, two different OAuth access methods

I'd like to create API supporting two different use cases. How should the authentication, proxy etc. to configure in APIgee Edge?

1) API is consumed by application where end-user is authenticated in third-party identity provider. I'm not interested how authentication has been done in the app, but app has anyway got access token from identity provider. When request comes to APIgee platform with this external access token, I just want to make sure the token is valid and forward request to backend.

2) Same API than earlier, but now the API consumer is application where end-user is not authenticated and can't do that. We can provide OAuth 2.0 client credential authentication internally in APIgee for consuming application. App is authenticated in APIgee and it provides access_token to app.

So, API request can have external or internal access token depending on the client. Can I somehow provide single API endpoint that could somehow handle both use cases? At least I don't want to implement two totally separate APIs.

Comment
Add comment
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

Close

1 Answer

  • Sort: 
avatar image
2
Best Answer

Answer by Dino-at-Google   · Sep 07, 2018 at 07:19 PM

Well sure, you can do that in Apigee Edge. The key is to insert a condition that examines the type of authentication. You will need a way to distinguish between requests that carry an "external access token" and an Apigee-issued token. I guess the form of both will be to pass a token in the Authorization header in the normal fashion, like this:

Authorization: Bearer TOKEN_GOES_HERE

By the way, I am inferring from your description that when you say "external access token", you are referring to a token that Apigee Edge does not store. The reason I point this out: it is possible for Apigee Edge to "ingest" an externally-generated access token and to then store it. Validation of this externally-generated access token would work the same way as validation for a token that is generated by Apigee Edge directly. I want to clarify that this is not the scenario you are referring to.

I am imagining that the "external access token" is a JWT. You said "I just want to make sure the token is valid". Supposing it is a JWT, and you have the public key that allows you to validate the token, you can use the VerifyJWT policy to validate it. For an Apigee-generated (opaque) OAuth token, you would use the OAuthV2/VerifyAccessToken policy to verify.

In either case after verification your API Proxy can pass through the request.

The only tricky bit is distinguishing the JWT from the opaque token.

The way I would do this, look for the JWT format - a string consisting of 3 segments separated by dots. If you see this, then assume it's the externally-provided JWT you want to accept; in this case call VerifyJWT. If not, then treat it as an opaque token; call VerifyAccessToken.

The flow looks like this:

    <Flow name="flow1">
      <Request>
        <Step>
          <Name>RaiseFault-MissingAuthentication</Name>
          <Condition>request.header.Authorization = null</Condition>
        </Step>


        <Step>
          <Name>VerifyJWT</Name>
          <Condition>request.header.Authorization ~~ "[Bb]earer *[-_a-zA-Z0-9]{2,}\.[-_a-zA-Z0-9]{2,}\.[-_a-zA-Z0-9]{2,}"</Condition>
        </Step>


        <Step>
          <Name>OAuthV2_VerifyToken</Name>
          <Condition>NOT(request.header.Authorization ~~ "[Bb]earer *[-_a-zA-Z0-9]{2,}\.[-_a-zA-Z0-9]{2,}\.[-_a-zA-Z0-9]{2,}")</Condition>
        </Step>


      </Request>
      <Response>
        <Step>
          <Name>AM-Response</Name>
        </Step>
      </Response>
      <Condition>(proxy.pathsuffix MatchesPath "/t1") and (request.verb = "GET")</Condition>
    </Flow>


To be clearer and comply with the DRY principle, you could evaluate that regex once, and store the result in a variable, and then just test the variable. like this:

    <Flow name="flow1">
      <Request>
        <Step>
          <Name>RaiseFault-MissingAuthentication</Name>
          <Condition>request.header.Authorization = null</Condition>
        </Step>


        <Step>
          <Name>AssignVariable_UsingJWT</Name>
          <Condition>request.header.Authorization ~~ "[Bb]earer *[-_a-zA-Z0-9]{2,}\.[-_a-zA-Z0-9]{2,}\.[-_a-zA-Z0-9]{2,}"</Condition>
        </Step>


        <Step>
          <Name>VerifyJWT</Name>
          <Condition>using_jwt != null</Condition>
        </Step>


        <Step>
          <Name>OAuthV2_VerifyToken</Name>
          <Condition>using_jwt = null</Condition>
        </Step>

      </Request>
      <Response>
        <Step>
          <Name>AM-Response</Name>
        </Step>
      </Response>
      <Condition>(proxy.pathsuffix MatchesPath "/t1") and (request.verb = "GET")</Condition>
    </Flow>


This bit of hieroglyphics

request.header.Authorization ~~ "..."

is just testing the Authorization header against a regular expression. The regex I used is pretty simple and it tests for the form of a JWT. The AssignVariable_UsingJWT would have to be something like this:

<AssignMessage name='AssignVariable_UsingJWT'>
  <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
  <AssignVariable>
    <Name>using_jwt</Name>
    <Value>true</Value>
  </AssignVariable>
</AssignMessage>

One or the other Verify policy will execute, and will throw a fault if the token is invalid.

Comment
Add comment · Link
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

Follow this Question

Answers Answers and Comments

93 People are following this question.

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

Related Questions

About OAuth2.0 Policy which is used to Generate Access Token using client credentials grant type 1 Answer

How can we pass dynamic access token to every API request through authentication? 1 Answer

Does Apigee know if an API request comes from a specific app, or can someone use a key for one app in 50 places? 0 Answers

How do I use an external access token in Apigee? 1 Answer

OAuth call from Apigee to the backend service that issues access token 0 Answers

  • 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