Skip to content

an API proxy that dispenses tokens in exchange for a Firebase ID token

Notifications You must be signed in to change notification settings

DinoChiesa/Apigee-OAuth-Firebase-ID

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 

Repository files navigation

OAuth v2.0 Token Dispensing Proxy - jwt-bearer Grant

This is an example Apigee proxy that illustrates how to use Apigee to dispense tokens, using an ID token generated by Firebase Auth, for the user credential. It will use the grant type of urn:ietf:params:oauth:grant-type:jwt-bearer.

The tokens dispensed here are opaque OAuth 2.0 access tokens.

This example has been tested with Apigee X.

Disclaimer

This example is not an official Google product, nor is it part of an official Google product.

License

This material is Copyright 2024, Google LLC. and is licensed under the Apache 2.0 license. See the LICENSE file.

This code is open source but you don't need to compile it in order to use it.

Setting up

  1. modify the VerifyJWT-Firebase-Id-Token policy to replace your-project-id with your project ID, in two places.

  2. Install the apigeecli tool, if you don't have it.

    curl -s https://raw.githubusercontent.com/apigee/apigeecli/master/downloadLatest.sh | bash
    export PATH=$PATH:$HOME/.apigeecli/bin
  3. Import the proxy into any Apigee organization.

    TOKEN=$(gcloud auth print-access-token)
    ORG=my-apigee-org
    ENV=my-apigee-env
    apigeecli apis create bundle -f apiproxy --name oauth2-firebase-id -o $ORG --token $TOKEN
    apigeecli apis deploy --wait --name oauth2-firebase-id --ovr --org $ORG --env $ENV --token $TOKEN
  4. Create an API product. The API product normally wraps API proxies with metadata. For the purposes of this example, your API product need not contain any API proxies. This is because in this example, we do not actually verify the token in this example. We only issue the token.

    PRODUCT_NAME=apigee-test-product
    apigeecli products create --name "${PRODUCT_NAME}" --displayname "${PRODUCT_NAME}" \
       --envs "$ENV" --approval auto \
       --org "$ORG" --token "$TOKEN"
  5. Create a Developer within Apigee

    DEVELOPER_EMAIL="example-developer@cymbalgroup.com"
    apigeecli developers create --user "${DEVELOPER_EMAIL}" --email "${DEVELOPER_EMAIL}" \
      --first Example --last Developer \
      --org "$ORG" --token "$TOKEN"
  6. Create a Developer App within Apigee, which is associated to the new Developer, and with authorization to use the API product.

    APP_NAME=example-app-1
    apigeecli apps create --name "${APP_NAME}" --email "${DEVELOPER_EMAIL}" \
      --prods "${PRODUCT_NAME}" --org "$ORG" --token "$TOKEN"

    View and copy the consumerKey :

    CLIENT_ID=value-from-consumerKey-in-the-output

Using the proxy to get a token

  1. Obtain your Firebase Auth ID token. (This step is left to you)

  2. With that ID token, and the client ID you obtained in the setup step, invoke the access-token-dispensing proxy to generate and retrieve a token:

    endpoint=https://endpoint-for-your-apigee-environment.io
    FIREBASE_ID_TOKEN=eyJhbGciOiJSUzI1N...full-token-here
    curl -i -X POST -H 'content-type: application/x-www-form-urlencoded' \
      "$endpoint/oauth2-firebase-id/token" \
      -d 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
      -d "client_id=$CLIENT_ID" \
      -d "assertion=$FIREBASE_ID_TOKEN"
    

    The response you see will look like this:

    HTTP/2 200
    token: access_token=b9g7tIQa2niYB9pYWALw6Rv6mhkW
    content-length: 321
    date: Tue, 09 Jan 2024 18:25:42 GMT
    via: 1.1 google
    
    {
      "token_type": "Bearer",
      "access_token": "b9g7tIQa2niYB9pYWALw6Rv6mhkW",
      "expires_in": 1799,
      "issued_at": 1704824742674,
      "refresh_token": "IU89ziyPrwsRgqupAAGvPiXpo7hs2oi3",
      "authenticated_user": "dchiesa001@gmail.com",
      "auth_time": 1704824425,
      "refresh_token_expires_in": 86399,
      "refresh_count": "0"
    }

    The access token is an opaque access token. You can then use it as a bearer token for invoking APIs managed within Apigee. That is not shown in this example.

Commentary

This API proxy dispenses opaque OAuth access tokens, using the jwt-bearer grant type. Essentially,

  • Apigee uses the Firebase-generated ID token to authenticate the user
  • Apigee uses the client ID to authenticater or identify the client app

If both of those are successful, Apigee generates an access token. The access token includes a custom attribute, stored internally in the key-management database within Apigee, containing the email of the user that was originally authenticated by Firebase.

Later, when you use OAuthV2/VerifyAccessToken on that token, your proxy wil be able to see the value of that custom attribute, and identify the originally authenticated user.

The tokens issued by this API proxy are "opaque", and are not JWT. JWT is one possible format for tokens. An opaque token, just a random string, is another possible format. Apigee can generate and return JWT, that function in much the same way as the opaque oauth tokens shown here. This is not implemented in this example API Proxy.

Teardown

  1. get the ID of the developer:

    apigeecli developers get --email "${DEVELOPER_EMAIL}" --org "$ORG" --token "$TOKEN"
    DEVELOPER_ID=...resulting developerId from above...
  2. remove the developer app

    apigeecli apps delete --id "${DEVELOPER_ID}" --name "${APP_NAME}" --org "$ORG" --token "$TOKEN"
  3. remove the developer

    apigeecli developers delete --email "${DEVELOPER_EMAIL}" --org "$ORG" --token "$TOKEN"
  4. delete the example API product

    apigeecli products delete --name "${PRODUCT_NAME}" --org "$ORG" --token "$TOKEN"
  5. get the revision of the deployed API proxy:

    apigeecli apis listdeploy --name "oauth2-firebase-id" --org "$ORG" --token "$TOKEN"
    REV=...revision-from-above...

    Then undeploy it:

    apigeecli apis undeploy --name "oauth2-firebase-id" --env "$ENV" --rev "$REV" --org "$ORG" --token "$TOKEN"
  6. delete the API proxy:

    apigeecli apis delete --name "oauth2-firebase-id" --org "$ORG" --token "$TOKEN"

Done.

About

an API proxy that dispenses tokens in exchange for a Firebase ID token

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published