Authenticate APIs
In this article, we will explore how to use Kong’s OAuth 2.0 plugin to authenticate APIs. Kong is an open-source API gateway that provides powerful capabilities for managing, securing, and scaling APIs. By leveraging Kong’s OAuth 2.0 plugin, you can easily add authentication and authorization mechanisms to your APIs. We will walk through the process of setting up Kong, creating services and routes, enabling the OAuth 2.0 plugin, and securing your APIs with OAuth 2.0 authentication.
Setting up Kong
Before we dive into the authentication process, let’s briefly cover the steps to set up Kong:
To learn how to set up Kong using Docker Compose, please refer to the following guide: Deploying Kong with Docker Compose. The guide provides detailed instructions on how to orchestrate and deploy Kong using Docker Compose.
Authenticate APIs using OAuth 2.0
- Create a Service: Use cURL or the Kong Admin API to create a service that represents your API. Specify the service name and the target URL where your API is hosted.
1 2 3 4
# Create a service curl -X POST http://localhost:8001/services \ --data "name=example-service" \ --data "url=http://backend-service:5000"
The returned data is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{ "name": "example-service", "write_timeout": 60000, "retries": 5, "tags": null, "ca_certificates": null, "tls_verify": null, "port": 8100, "client_certificate": null, "connect_timeout": 60000, "created_at": 1689911694, "updated_at": 1689911694, "path": null, "protocol": "http", "host": "backend-service", "read_timeout": 60000, "id": "977ab5e5-81b6-465f-ae53-68a61413b6ad", "tls_verify_depth": null }
- Create a Route: Define a route for your service to specify how incoming requests should be routed. You can define routing rules based on hostnames, paths, or other criteria.
1 2 3 4 5
# Create a route curl -X POST http://localhost:8001/services/example-service/routes \ --data "name=example-endpoint" \ --data "paths[]=/api/your-endpoint" \ --data "service.id=977ab5e5-81b6-465f-ae53-68a61413b6ad"
The returned data is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
{ "name": null, "response_buffering": true, "tags": null, "https_redirect_status_code": 426, "preserve_host": false, "protocols": [ "http", "https" ], "hosts": [ "example-service" ], "service": { "id": "977ab5e5-81b6-465f-ae53-68a61413b6ad" }, "headers": null, "created_at": 1689914888, "updated_at": 1689914888, "snis": null, "regex_priority": 0, "paths": [ "/api/your-endpoint" ], "methods": null, "sources": null, "destinations": null, "path_handling": "v0", "request_buffering": true, "id": "5c967161-2409-46dd-b8f9-822174104f8b", "strip_path": true }
- Create a Consumer: Create a consumer entity to represent the end-user or client accessing your API. This can be an individual user or an application.
1 2 3
# Create a consumer curl -X POST http://localhost:8001/consumers \ --data "username=example-user"
The returned data is as follows:
1 2 3 4 5 6 7
{ "created_at": 1688718407, "custom_id": null, "tags": null, "id": "2726d40d-5d70-42fe-9316-74fde9c9b42e", "username": "example-user" }
- Enable the OAuth 2.0 Plugin: Enable the OAuth 2.0 plugin on the service or route level to secure your API with OAuth 2.0 authentication. Configure the plugin to specify the desired OAuth 2.0 settings, such as enabled grant types, scopes, and other options.
1 2 3 4 5 6 7 8 9
# Enable the OAuth 2.0 plugin curl -X POST http://localhost:8001/services/example-service/plugins \ --data "name=oauth2" \ --data "config.enable_client_credentials=true" \ --data "config.enable_authorization_code=true" \ --data "config.enable_implicit_grant=true" \ --data "config.enable_password_grant=true" \ --data "config.mandatory_scope=true" \ --data "config.scopes=email"
The returned data is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
{ "consumer": null, "id": "9c160e1d-9047-4fea-ac15-68b1ed88a6a6", "config": { "mandatory_scope": false, "auth_header_name": "authorization", "anonymous": null, "enable_implicit_grant": true, "enable_authorization_code": true, "accept_http_if_already_terminated": false, "enable_password_grant": true, "refresh_token_ttl": 1209600, "hide_credentials": false, "provision_key": "Acy9zQ7v4KGXPcWA4vLz0uEsJwwE7iZZ", "token_expiration": 7200, "scopes": [ "email" ], "global_credentials": false, "reuse_refresh_token": false, "pkce": "lax", "enable_client_credentials": true }, "protocols": [ "grpc", "grpcs", "http", "https" ], "created_at": 1684227513, "name": "oauth2", "tags": null, "route": null, "service": { "id": "59328986-a83e-4231-9456-505dce8e7ee7" }, "enabled": true }
- Create OAuth 2.0 Credentials: Generate OAuth 2.0 credentials (client ID and client secret) for your consumer. These credentials will be used by the consumer to authenticate and obtain access tokens.
1 2 3 4 5 6
# Create OAuth 2.0 credentials curl -k -X POST https://localhost:8443/consumers/example-user/oauth2 \ --data "name=your-credential-name" \ --data "client_id=your-client-id" \ --data "client_secret=your-client-secret" \ --data "redirect_uris=http://backend-service:5000"
Here, if the client_id and client_secret are specified, Kong will use the provided values. However, if they are not specified, Kong will automatically generate random values for client_id and client_secret.
- To obtain an OAuth 2.0 access token, use the following command:
1 2 3 4 5 6 7 8 9
# Get an OAuth 2.0 access token curl -k -X POST https://localhost:8443/api/your-endpoint/oauth2/token \ --data "grant_type=password" \ --data "client_id=your-client-id" \ --data "client_secret=your-client-secret" \ --data "username=user@example.com" \ --data "password=your-password" \ --data "authenticated_userid": "your-authenticated-userid" \ --data "provision_key": "your-provision-key"
Here, we make a POST request to the token endpoint, specifying the grant type as “password”. Provide the authenticated_userid, provision_key, client ID, client secret, username, and password as parameters to retrieve the access token.
authenticated_userid
is the value of the return ID in step 3Create a Consumer
, such as “2726d40d-5d70-42fe-9316-74fde9c9b42e”. The returned data is as follows:1 2 3 4 5 6
{ "refresh_token": "8BWZ6GY31mqAYJGvnoxp1rIBT9QlBBSz", "token_type": "bearer", "expires_in": 7200, "access_token": "1Go0lynUqrpWwV2mp49L7WGUc8UjvQSU" }
- Include the Access Token: After successfully obtaining an access token, include it in the
Authorization
header of subsequent API requests as a bearer token. Kong will validate the access token and grant access to the protected API endpoints if it’s valid.1 2 3 4 5
# Get an OAuth 2.0 access token curl -X POST http://localhost:8000/api/your-endpoint \ --header "authorization: bearer your-access-token" \ --header "content-type: application/json" \ --data-raw '{"your-key": "your-value"}'
- If access tokens expire, you can use the refresh token grant type to obtain a new access token without requiring user credentials. If you need to refresh an OAuth 2.0 access token, use the following command:
1 2 3 4 5 6
# Refresh an OAuth 2.0 access token curl -k -X POST https://localhost:8433/api/your-endpoint/oauth2/token \ --data "grant_type=refresh_token" \ --data "client_id=your-client-id" \ --data "client_secret=your-client-secret" \ --data "refresh_token=your-refresh-token"
In this case, we send a POST request to the token endpoint with the grant type set to “refresh_token”. Provide the client ID, client secret, and refresh token as parameters to refresh the access token.
- If you want to delete an OAuth 2.0 token, use the following command:
1 2
# Delete an OAuth 2.0 token curl -X DELETE http://localhost:8001/oauth2_tokens/your-token-id
Make a DELETE request to the endpoint
/oauth2_tokens/your-token-id
, whereyour-token-id
represents the specific OAuth 2.0 token you wish to delete.
— Fugui,Data engineer、Machine learning Engineer、Software Engineer.