Note: As per the OAuth2 specs, this plugin requires the
underlying service to be served over HTTPS. To avoid any
confusion, we recommend that you configure the Route used to serve the
underlying Service to only accept HTTPS traffic (via its `protocols`
property).

Note: The functionality of this plugin as bundled
with versions of Kong prior to 0.12.0
differs from what is documented herein. Refer to the
CHANGELOG
for details.

Terminology

plugin: a plugin executing actions inside Kong before or after a request has been proxied to the upstream API.

upstream service: this refers to your own API/service sitting behind Kong, to which client requests are forwarded.

Configuration

This plugin is compatible with requests with the following protocols:

http

https

This plugin is not compatible with DB-less mode.

For its regular work, the plugin needs to both generate and delete tokens, and commit those changes to the database, which is not compatible with DB-less.
In addition to this, its Admin API endpoints offer several POST, PATCH, PUT and DELETE methods for tokens and credentials. None of them would work on DB-less.

In both cases, {service} is the id or name of the Service that this plugin configuration will target.

Global plugins

Using a database, all plugins can be configured using the http://kong:8001/plugins/ endpoint.

Without a database, all plugins can be configured via the plugins: entry on the declarative configuration file.

A plugin which is not associated to any Service, Route or Consumer (or API, if you are using an older
version of Kong) is considered "global", and will be run on every request.
Read the Plugin Reference and the
Plugin Precedence sections for more information.

Parameters

Here's a list of all the parameters which can be used in this plugin's configuration:

form parameter

description

name

The name of the plugin to use, in this case oauth2

service_id

The id of the Service which this plugin will target.

enabled

default value: true

Whether this plugin will be applied.

config.scopes

Describes an array of scope names that will be available to the end user

config.mandatory_scopeoptional

default value:

false

An optional boolean value telling the plugin to require at least one scope to be authorized by the end user

config.token_expirationoptional

default value:

7200

An optional integer value telling the plugin how many seconds a token should last, after which the client will need to refresh the token. Set to 0 to disable the expiration.

The name of the header supposed to carry the access token. Default: authorization.

config.hide_credentialsoptional

default value:

false

An optional boolean value telling the plugin to show or hide the credential from the upstream service. If true, the plugin will strip the credential from the request (i.e. the header containing the client credentials) before proxying it.

config.accept_http_if_already_terminatedoptional

default value:

false

Accepts HTTPs requests that have already been terminated by a proxy or load balancer and the x-forwarded-proto: https header has been added to the request. Only enable this option if the Kong server cannot be publicly accessed and the only entry-point is such proxy or load balancer.

config.anonymousoptional

An optional string (consumer uuid) value to use as an “anonymous” consumer if authentication fails. If empty (default), the request will fail with an authentication failure 4xx. Please note that this value must refer to the Consumer id attribute which is internal to Kong, and not its custom_id.

config.global_credentialsoptional

default value:

false

An optional boolean value that allows to use the same OAuth credentials generated by the plugin with any other Service whose OAuth 2.0 plugin configuration also has config.global_credentials=true.

config.refresh_token_ttloptional

default value:

1209600

An optional integer value telling the plugin how many seconds a token/refresh token pair is valid for, and can be used to generate a new access token. Default value is 2 weeks. Set to 0 to keep the token/refresh token pair indefinitely valid.

The option config.refresh_token_ttl is only available from version 0.12.0 and later

Once applied, any user with a valid credential can access the Service.
To restrict usage to only some of the authenticated users, also add the
ACL plugin (not covered here) and create whitelist or
blacklist groups of users.

Usage

In order to use the plugin, you first need to create a consumer to associate one or more credentials to. The Consumer represents a developer using the upstream service.

Note: This plugin requires a database in order to work effectively. It *does not* work on DB-Less mode.

Endpoints

By default the OAuth 2.0 plugin listens on the following endpoints when a client consumes the underlying Service via the proxy port:

Endpoint

description

/oauth2/authorize

The endpoint to the Authorization Server that provisions authorization codes for the Authorization Code flow, or the access token when the Implicit Grant flow is enabled. Only POST is supported.

The clients trying to authorize and request access tokens must use these endpoints. Remember that the endpoints above must be combined with the right URI path or headers that you normally use to match a configured Route through Kong.

Create a Consumer

You need to associate a credential to an existing Consumer object. To create a Consumer, you can execute the following request:

You can optionally set your own access token value, otherwise a random string will be generated.

refresh_tokenoptional

You can optionally set your own unique refresh token value, otherwise a random string will be generated.

expires_in

The expiration time (in seconds) of the access token.

scopeoptional

The authorized scope associated with the token.

authenticated_useridoptional

The custom ID of the user who authorized the application.

Upstream Headers

When a client has been authenticated and authorized, the plugin will append some headers to the request before proxying it to the upstream service, so that you can identify the consumer and the end-user in your code:

X-Consumer-ID, the ID of the Consumer on Kong

X-Consumer-Custom-ID, the custom_id of the Consumer (if set)

X-Consumer-Username, the username of the Consumer (if set)

X-Authenticated-Scope, the comma-separated list of scopes that the end user has authenticated, if available (only if the consumer is not the ‘anonymous’ consumer)

X-Authenticated-Userid, the logged-in user ID who has granted permission to the client (only if the consumer is not the ‘anonymous’ consumer)

X-Anonymous-Consumer, will be set to true when authentication failed, and the ‘anonymous’ consumer was set instead.

You can use this information on your side to implement additional logic. You can use the X-Consumer-ID value to query the Kong Admin API and retrieve more information about the Consumer.

OAuth 2.0 Flows

Client Credentials

The Client Credentials flow will work out of the box, without building any authorization page. The clients will need to use the /oauth2/token endpoint to request an access token.

Authorization Code

After provisioning Consumers and associating OAuth 2.0 credentials to them, it is important to understand how the OAuth 2.0 authorization flow works. As opposed to most of the Kong plugins, the OAuth 2.0 plugin requires some little additional work on your side to make everything work well:

You must implement an authorization page on your web application, that will talk with the plugin server-side.

Optionally you need to explain on your website/documentation how to consume your OAuth 2.0 protected services, so that developers accessing your service know how to build their client implementations

The flow explained

Building the authorization page is going to be the primary task that the plugin itself cannot do out of the box, because it requires to check that the user is properly logged in, and this operation is strongly tied with your authentication implementation.

The authorization page is made of two parts:

The frontend page that the user will see, and that will allow him to authorize the client application to access his data

The backend that will process the HTML form displayed in the frontend, that will talk with the OAuth 2.0 plugin on Kong, and that will ultimately redirect the user to a third party URL.

The client application will redirect the end user to the authorization page on your web application, passing client_id, response_type and scope (if required) as querystring parameters. This is a sample authorization page:

Before showing the actual authorization page, the web application will make sure that the user is logged in.

The client application will send the client_id in the querystring, from which the web application can retrieve both the OAuth 2.0 application name, and developer name, by making the following request to Kong:

$ curl kong:8001/oauth2?client_id=XXX

If the end user authorized the application, the form will submit the data to your backend with a POST request, sending the client_id, response_type and scope parameters that were placed in <input type="hidden" .. /> fields.

The backend must add the provision_key and authenticated_userid parameters to the client_id, response_type and scope parameters and it will make a POST request to Kong at your Service address, on the /oauth2/authorize endpoint. If an Authorization header has been sent by the client, that must be added too. The equivalent of:

The provision_key is the key the plugin has generated when it has been added to the Service while authenticated_userid is the ID of the logged-in end user who has granted the permission.

Kong will respond with a JSON response:

{"redirect_uri":"http://some/url"}

With either a 200 OK or 400 Bad Request response code depending if the request was successful or not.

In both cases, ignore the response status code and just redirect the user to whatever URI is being returned in the redirect_uri property.

The client application will take it from here, and will continue the flow with Kong with no other interaction with your web application. Like exchanging the authorization code for an access token if it’s an Authorization Code Grant flow.

Once the Access Token has been retrieved, the client application will make requests on behalf of the user to your upstream service.

Access Tokens can expire, and when that happens the client application needs to renew the Access Token with Kong and retrieve a new one.

In this flow, the steps that you need to implement are:

The login page, you probably already have it (step 2)

The Authorization page, with its backend that will simply collect the values, make a POST request to Kong and redirect the user to whatever URL Kong has returned (steps 3 to 7).

Resource Owner Password Credentials

The Resource Owner Password Credentials Grant is a much simpler version of the Authorization Code flow, but it still requires to build an authorization backend (without the frontend) in order to make it work properly.

On the first request, the client application make a request including some OAuth2 parameters, including username and password parameters, to your web-application.

The backend of your web-application will authenticate the username and password sent by the client, and if successful will add the provision_key, authenticated_userid and grant_type parameters to the parameters originally sent by the client, and it will make a POST request to Kong at, on the /oauth2/token endpoint of the configured plugin. If an Authorization header has been sent by the client, that must be added too. The equivalent of:

The provision_key is the key the plugin has generated when it has been added to the Service, while authenticated_userid is the ID of the end user whose username and password belong to.

Kong will respond with a JSON response

The JSON response sent by Kong must be sent back to the original client as it is. If the operation is successful, this response will include an access token, otherwise it will include an error.

In this flow, the steps that you need to implement are:

The backend endpoint that will process the original request and will authenticate the username and password values sent by the client, and if the authentication is successful, make the request to Kong and return back to the client whatever response Kong has sent back.

Refresh Token

When your access token expires, you can generate a new access token using the refresh token you received in conjunction to your expired access token.