The OAuth plugin issues OAuth 2.0 access tokens based on JSON Web Tokens (JWTs), compliant with RFC 9068.
Plugin type
Authentication and authorization.
Plugin configuration
Fields
Authorization configuration
|
Field |
Data type |
Required |
Default value |
Description |
|
consumers |
array of object |
Yes |
- |
Callers (consumers) allowed to request authentication. |
|
issuer |
string |
No |
Higress-Gateway |
JWT issuer. |
|
auth_path |
string |
No |
/oauth2/token |
Path suffix for token issuance. Ensure the route matches this path. If you use API management, create an API with the same path. |
|
global_credentials |
bool |
No |
true |
Whether credentials issued on any route grant access after consumer authentication succeeds. |
|
auth_header_name |
string |
No |
Authorization |
Request header containing the JWT. |
|
token_ttl |
number |
No |
7200 |
Token time-to-live after issuance, in seconds. |
|
clock_skew_seconds |
number |
No |
60 |
Allowed clock skew for JWT exp and iat verification, in seconds. |
|
keep_token |
bool |
No |
true |
Whether to keep the JWT in requests forwarded to the backend. |
|
global_auth |
array of string |
No (Required only for instance-level configurations) |
- |
Instance-level only. If set to true, authentication applies to all routes. If set to false, authentication applies only to configured domains and routes. If left unset, authentication applies globally only when no domain- or route-level configurations exist. |
Fields in consumers:
|
Field |
Data type |
Required |
Default value |
Description |
|
name |
string |
Yes |
- |
Consumer name. |
|
client_id |
string |
Yes |
- |
OAuth 2.0 client ID. |
|
client_secret |
string |
Yes |
- |
OAuth 2.0 client secret. |
-
If a route matches
auth_path, the request is not forwarded to the backend. Instead, the route generates a token. -
If
global_credentialsis false, ensure the route with the plugin enabled does not use exact match. A coexisting prefix-match route may cause unexpected behavior. -
For authenticated requests, an
X-Mse-Consumerheader is added to identify the caller.
(Optional) Authorization configuration
|
Field |
Data type |
Required |
Default value |
Description |
|
allow |
array of string |
No (Required for non-instance-level configurations) |
- |
Route- or domain-level only. Specifies which consumers can access matching requests for fine-grained permission control. |
Authorization and authentication configurations cannot coexist in the same rule.
Examples
Route-level authorization configuration
Apply the following plugin configuration to route-a and route-b:
consumers:
- name: consumer1
client_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_secret: abcdefgh-xxxx-xxxx-xxxx-xxxxxxxxxxxx
With this configuration, credentials issued by route-a cannot access route-b and vice versa.
To share credentials across routes:
global_credentials: true
consumers:
- name: consumer1
client_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_secret: abcdefgh-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Global authorization configuration and route-level authentication configuration
The following configuration enables JWT authentication for specific routes or domains. If a JWT matches multiple JSON Web Key Sets (JWKSs), the first matching consumer takes effect.
Instance-level configuration:
global_auth: false
consumers:
- name: consumer1
client_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_secret: abcdefgh-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- name: consumer2
client_id: 87654321-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_secret: hgfedcba-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Configuration for route-a and route-b:
allow:
- consumer1
Configuration for *.example.com and test.com:
allow:
- consumer2
-
route-aandroute-bare gateway routes. Requests matching these routes allow only the consumer namedconsumer1. -
*.example.comandtest.commatch domain names in requests. Requests matching these domains allow only the consumer namedconsumer2.
Enable authentication at the gateway level
Enable OAuth2 authentication for all gateway requests:
global_auth: true
consumers:
- name: consumer1
client_id: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_secret: abcdefgh-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- name: consumer2
client_id: 87654321-xxxx-xxxx-xxxx-xxxxxxxxxxxx
client_secret: hgfedcba-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Request examples
Use the Client Credential grant type
Obtain an access token
# Obtain an access token by using the GET method. We recommend that you use this method.
curl 'http://test.com/oauth2/token?grant_type=client_credentials&client_id=12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx&client_secret=abcdefgh-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
# Obtain an access token by using the POST method. To perform this operation, you need to match a route that points to a real destination service. Otherwise, the gateway does not read request bodies.
curl 'http://test.com/oauth2/token' -H 'content-type: application/x-www-form-urlencoded' -d 'grant_type=client_credentials&client_id=12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx&client_secret=abcdefgh-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
# Obtain the value of the access_token field from the response.
{
"token_type": "bearer",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6ImFwcGxpY2F0aW9uXC9hdCtqd3QifQ.eyJhdWQiOiJkZWZhdWx0IiwiY2xpZW50X2lkIjoiMTIzNDU2NzgteHh4eC14eHh4LXh4eHgteHh4eHh4eHh4eHh4IiwiZXhwIjoxNjg3OTUxNDYzLCJpYXQiOjE2ODc5NDQyNjMsImlzcyI6IkhpZ3Jlc3MtR2F0ZXdheSIsImp0aSI6IjEwOTU5ZDFiLThkNjEtNGRlYy1iZWE3LTk0ODEwMzc1YjYzYyIsInN1YiI6ImNvbnN1bWVyMSJ9.NkT_rG3DcV9543vBQgneVqoGfIhVeOuUBwLJJ4Wycb0",
"expires_in": 7200
}
Use the access token to initiate a request
curl 'http://test.com' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6ImFwcGxpY2F0aW9uXC9hdCtqd3QifQ.eyJhdWQiOiJkZWZhdWx0IiwiY2xpZW50X2lkIjoiMTIzNDU2NzgteHh4eC14eHh4LXh4eHgteHh4eHh4eHh4eHh4IiwiZXhwIjoxNjg3OTUxNDYzLCJpYXQiOjE2ODc5NDQyNjMsImlzcyI6IkhpZ3Jlc3MtR2F0ZXdheSIsImp0aSI6IjEwOTU5ZDFiLThkNjEtNGRlYy1iZWE3LTk0ODEwMzc1YjYzYyIsInN1YiI6ImNvbnN1bWVyMSJ9.NkT_rG3DcV9543vBQgneVqoGfIhVeOuUBwLJJ4Wycb0'
Error codes
|
HTTP status code |
Error message |
Reason |
|
401 |
Invalid Jwt token. |
The JWT is missing, malformed, or expired. |
|
403 |
Access Denied. |
The consumer is not authorized to access this route. |