Skip to content
This repository was archived by the owner on Jul 14, 2022. It is now read-only.

Adding OAuth

wwitman edited this page Sep 22, 2014 · 6 revisions

Adding OAuth 2.0 security to your API

This topic explains how to add OAuth 2.0 security to your Apigee-127 API using Volos.js configurations placed in the API's Swagger specification file.

Code samples

Both the weather-advanced and the example-project samples on GitHub demonstrate how to use OAuth 2.0 with an Apigee-127 app. You can clone those samples and examine the code directly, and see the README.md files provided with the samples for more details.

About Volos.js support for OAuth 2.0

Volos.js supports two implementations for adding OAuth 2.0 security to an API:

  • volos-oauth-redis: Uses Redis as a database for managing OAuth tokens and related activities.

  • volos-oauth-apigee: Communicates with Apigee Edge through APIs for managing OAuth tokens and related activities.

In this topic, we'll discuss using Apigee Edge as the token manager.

Overview of steps

The basic steps for adding OAuth 2.0 (with Apigee Edge as the token manager) to your Apigee-127 API are:

  1. Add the volos-oauth-apigee module to the dependencies list in package.json.
  2. Add required modules to the main Node.js app file (for example, app.jsin the Apigee 127 skeleton project).
  3. Add required Volos.js vendor extensions to the Swagger API specification file (using the Swagger editor).
  4. Apply the x-volos-authorizations Swagger extension to each path you wish to protect in the Swagger API specification file.
  5. Obtain an access token from the token manager (Apigee Edge in this example).
  6. Test your API.

1. Update dependencies in package.json

If it is not present already, add the volos-oauth-apigee module to your dependencies in package.json file.

Note: The skeleton project that is installed when you create a new Apigee-127 project already includes this dependency.

For example:

    "dependencies": {
         "express": "",
         "a127-magic": "",
         "volos-oauth-apigee": ""
    }

Important After updating package.json, you must run npm install.

Note: As mentioned previously, you can also use the Volos.js Redis implementation for OAuth. In that case, you would add the volos-oauth-redisdependency. More information here.

2. Add required components to the main Node.js file

You need to include the a127-magic and Apigee 127 middleware to your app's main file. For example, here's a minimal configuration. It is the same configuration found in the Apigee 127 skeleton app (the app.js file that is installed when you do a127 project create).

    var a127 = require('a127-magic');
    var express = require('express');
    app.use(express.bodyParser());
    var app = express();

    app.use(a127.middleware());

    app.listen(process.env.PORT || 10010);

3. Add Volos.js extensions to the Swagger specification file

  1. Execute a127 project edit to open up the Swagger editor.

  2. In the Swagger configuration file, configure the x-a127-config and x-volos-resources extensions as follows.

If you look at the default swagger.yaml file that is in the default skeleton project, you'll see the lines:

  x-a127-config: {}
  x-volos-resources: {}

Replace those lines with the following stanzas.

Important: Add these stanzas exactly as shown. These are top-level tags -- the extension names should be intented all the way to the left.

  x-a127-config:
    apigeeProxyKey: &apigeeProxyKey CONFIGURED
    apigeeProxyUri: &apigeeProxyUri CONFIGURED
  x-volos-resources:
    oauth2:
      provider: volos-oauth-apigee
      options:
        key: *apigeeProxyKey
        uri: *apigeeProxyUri
        validGrantTypes:
          - client_credentials
          - authorization_code
          - implicit_grant
          - password
        #passwordCheck:
          #helper: volos
          #function: passwordCheck
      paths:
        note: these will be placed in the paths section
        authorize: /authorize
        token: /accessToken
        invalidate: /invalidate
        refresh: /refresh

Note: For now, leave the passwordCheck stanza commented. We'll use it later when we discuss password credential type.

One more thing -- add x-www-form-urlencoded to the "consumes" part of the spec, like this:

  consumes:
    - application/json
    - application/x-www-form-urlencoded

4. Implement the passwordCheck function in api/helpers/volos.js

Here is the sample code. You can copy and paste it into api/helpers/volos.js.

module.exports.passwordCheck = passwordCheck;

function passwordCheck(username, password, cb) {
  // Implement as necessary
  var passwordOk = (username === 'scott' && password === 'apigee');
  cb(null, passwordOk);
}

5. Apply the OAuth 2.0 authorizations to the API paths

The last configuration step is to apply an oauth2 authorization to each path that you wish to protect. For example, for a path called /weather, you add the oauth2 authorization as follows:

    /weather:
        x-swagger-router-controller: weather
        x-volos-authorizations:
          oauth2: {}

6. Testing the app

To test the OAuth configuration, you need to obtain a bearer token from the OAuth server (Apigee in this example).

First, try calling the app. For example,

curl -i http://localhost:10010/hello?name=Scott

{"error_description":"Missing Authorization header","error":"missing_authorization"}

The request is rejected because you need to obtain and present an access token.

Requesting an access token using the client credentials method

Let's get an access token using the OAuth 2.0 Client Credentials method. In a following section, we'll show how to obtain a token using password credentials.

You can request an access token like this:

curl -X POST "http://localhost:10010/accesstoken" -d '{"grant_type":"client_credentials", "client_id":"xxxxxxx", "client_secret":"yyyyyy"}'

You can obtain the client_id and client_secret values directly from Apigee Edge through the management UI. Or, you can obtain them programmatically using Volos.js APIs. We'll discuss the programmatic method later in this topic.

###Obtaining keys directly from Apigee Edge

Here is the procedure:

You need to create a Developer App on Apigee Edge, then, you can obtain the keys from at App.

  1. Create a new Product. (Publish > Product and fill in the form. You do not have to select an API proxy for this exersize.)
  2. Create a new Developer. (Publish > Developer and fill out the form).
  3. Create a new Developer App. (Publish > Developer App and fill out the form, and click Save)
  4. Open the Developer App you just created. Click Show next to the Consumer Key and Consumer Secret fields.

alt text

  1. Substitute these values for the client_id and client_secret items in the /accesstoken API call.
  2. Execute the above curl command with the substituted values. Here's an example (piped to a Python utility that prints JSON in a nice, indented format):
  curl -X POST "http://localhost:10010/accesstoken" -d "grant_type=client_credentials&client_id=o2lxnymzY9iDkjXNgGtb9PsNJCZNJXVP&client_secret=S9vYUARVkADrDvc1" | python -m json.tool
  {
      "access_token": "7zSVVqNCsGYQKWDKy2C02XGOTUBA",
      "api_product_list": "[Test App product]",
      "api_profile_name": null,
      "application_name": "921c456d-77c0-4b31-9814-c1f7d4c47b8f",
      "client_id": "o2lxnymzY9iDkjXNgGtb9PsNJCZNJXVP",
      "developer_email": "[email protected]",
      "expires_in": 1799,
      "issued_at": 1411398701495,
      "organization_id": "0",
      "organization_name": "wwitman",
      "refresh_count": 0,
      "refresh_token": null,
      "refresh_token_expires_in": 0,
      "refresh_token_status": null,
      "scope": "",
      "state": null,
      "status": "approved",
      "token_type": "bearer"
  }

Now, you have an access token and you can execute the API by calling it like this:

curl -i "http://localhost:10010/hello?name=Scott" -H "Authorization: Bearer 7zSVVqNCsGYQKWDKy2C02XGOTUBA"

Requesting an access token using the password credentials method

If you want to use password credentials, you need a way to validate user credentials before retrieving an access token from Apigee. Here's how:

  1. Uncomment the passwordCheck stanza in the Swagger spec in the oauth2 options section. It specifies in which "helper" file the app can find the passwordCheck method. In this case, it looks in api/helpers/volos.js. The uncommented stanza should look like this:
   passwordCheck:
          helper: volos
          function: passwordCheck
  1. Implement the passwordCheck function in api/helpers/volos.js.

Here is the sample code. You can copy and paste it into api/helpers/volos.js.

Note: In reality, you might implement this method to verify the user's credentials in an LDAP system, for example.

module.exports.passwordCheck = passwordCheck;

function passwordCheck(username, password, cb) {
  // Implement as necessary
  var passwordOk = (username === 'scott' && password === 'apigee');
  cb(null, passwordOk);
}
  1. Start the app (a127 project start).
  2. Obtain the access token by calling this API (with the default values for username and password):

curl -X POST "http://localhost:10010/accesstoken" -d "grant_type=password&client_id=o2lxnymzY9iDkjXNgGtb9PsNJCZNJXVP&client_secret=S9vYUARVkADrDvc1&password=apigee&username=scott"

Obtaining the access token programmatically

You can find a working example where the Access token is fetched from Apigee Edge programmatically using Volos.js. The relevant code is in app.js in the example-project on GitHub.

You can also add caching, quotas, analytics, and deploy to Apigee.

Clone this wiki locally