11436 SSO

Tutorial: Securing your Apigee-127 API with OAuth 2.0

Dec 08, 2014

Let's continue our series on Apigee-127. This time, we'll walk through the basic steps for adding OAuth 2.0 security to an Apigee-127 API.

Why do you need OAuth?

Let's say an app needs to access account information from your bank. Do you want to give that app your banking password? Do you know who wrote the app or where it's running? How will the app protect your password? Can it be trusted?

OAuth 2.0 addresses this problem. It allows an app to request an access token from a trusted authorization server. The access token (a random-looking string) is a kind of stand-in for username/password credentials and gives the client app limited access to private data owned by the end user or by the app itself.

One nice thing about an access token is that it can be revoked at any time. Let's say your app is hacked. If you have OAuth, the hacker doesn't have your username and password—just an access token. That access token can be revoked, rendering it useless. And you won't have to change your login credentials for all of your bank accounts, social media sites, or whatever services that the app uses on your behalf.

Add an OAuth provider to your API

To use OAuth with Apigee-127, you need to add one of two OAuth providers to your API: Apigee or Redis. For this example, we'll use Apigee.

To use the Apigee OAuth service provider, you need to create an Apigee-127 account by specifying the "apigee" provider when prompted. This is required because, behind the scenes, Apigee-127 communicates with Apigee Edge to generate access tokens. All the details are handled for you when you create your account.

Add the provider to your project's swagger.yaml file as an x-a127-services extension, like this:

       provider: "volos-oauth-apigee"
         key: *apigeeProxyKey
         uri: *apigeeProxyUri
         tokenLifetime: 300000
           - client_credentials
           - authorization_code
           - implicit_grant
           - password
         tokenPaths: # These will be added to your paths section for you
           token: /accesstoken
           invalidate: /invalidate
           refresh: /refresh
           authorize: /authorize


Grant types

Grant types are essentially OAuth "flows" you can implement to obtain an access token. Each grant type is suited for a specific use case.

In this example, we're going to use the client credentials grant type. This grant type is best suited for cases where the client app is also the owner of the protected resources. For example, the app might require the use of cloud storage to do its work. An end user isn't really involved with this flow:

The token paths are API endpoints exposed by the authorization server (Apigee Edge in this example). An app makes API calls to these endpoints to obtain or refresh access tokens and perform other functions.

The key and uri values are generated for you when you create your Apigee-127 account with "apigee" as the provider. They allow Apigee-127 to communicate with Apigee Edge. The tokenLifetime parameter specifies, in milliseconds, when the generated token will expire.

Apply the OAuth provider to your API

Now that the provider is added, you need to apply it to whichever API paths you wish to protect. Here's how you would secure a path called /weather using the x-a127-authorizations extension. This configuration says: whenever /weather is called, enforce OAuth security!

       x-swagger-router-controller: weather
           oauth2: {}


Get an access token

To get an access token, you can make an API call to your local instance of Apigee-127. For example:

$ curl -X POST "https://localhost:10010/accesstoken" -d "grant_type=client_credentials&client_id=hTYG6fcQGpsO9ZvRke1MiQZ4GAJ&client_secret=we2YiMkZ1vjC"

The parameters are all required. The grant_type parameter simply identifies the grant type so the authorization server knows what to expect. But what about client_id and client_secret?

Briefly, these values come from an app that is registered with the authorization server. Upon successful registration, client ID and client secret keys are generated for the app along with some other metadata. They enable the authorization server to uniquely identify the source of an API call when it receives requests, and are required for most OAuth interactions.

On Apigee Edge, you can register and discover developer apps under the Publish > Developer Apps menu.

Call the API with the access token

To call your secured API, you need to send the access token with every request to a protected path (such as /weather in our example). Access tokens are submitted in the request header as a "Bearer" token. For example:

curl -i -H 'Authorization: Bearer 3JTnOwzrfTtnbMGDdys2ZymGAA7t' 

When Apigee-127 receives this request, it validates the access token, and, if the token is valid, the API call proceeds to the target.

Code samples and more

If you'd like to try out a complete, working example, see the oauth-cc-example in the Apigee-127 samples repo on GitHub. It's easy to install and run, and the README explains how it works. Also, check out our password grant type example.

The IETF OAuth 2.0 specification includes a good introduction to OAuth 2.0 and each of the grant types.

In a future blog, we'll look at how to use OAuth 2.0 scopes to limit an app's access to protected data. In the meantime, visit our Apigee-127 YouTube playlist.

Scaling Microservices