このページは、まだ日本語ではご利用いただけません。翻訳中です。
古いプラグインバージョンのドキュメントを閲覧しています。
Refresh token grant workflow
The refresh token grant can be used when the client has a refresh token available. There is a caveat with this: identity providers in general only allow refresh token grant to be executed with the same client that originally got the refresh token, and if there is a mismatch, it may not work. The mismatch is likely when Kong OpenID Connect is configured to use one client, and the refresh token is retrieved with another. The grant itself is very similar to the password grant and the client credentials grant:
sequenceDiagram
autonumber
participant client as Client
(e.g. mobile app)
participant kong as API Gateway
(Kong)
participant idp as IDP
(e.g. Keycloak)
participant httpbin as Upstream
(backend service,
e.g. httpbin)
activate client
activate kong
client->>kong: service with
refresh token
deactivate client
kong->>kong: load refresh token
activate idp
kong->>idp: keycloak/token with
client credentials and
refresh token
deactivate kong
idp->>idp: authenticate client and
verify refresh token
activate kong
idp->>kong: return tokens
deactivate idp
kong->>kong: verify tokens
activate httpbin
kong->>httpbin: request with access token
httpbin->>kong: response
deactivate httpbin
activate client
kong->>client: response
deactivate kong
deactivate client
Prerequisites
In most cases, the OpenID Connect plugin relies on a third party identity provider (IdP). The examples in this guide use Keycloak as a sample IdP.
Expand the following sections to configure Keycloak and Kong Gateway.
Configure Keycloak
All the *.test domains in the following examples point to the localhost (127.0.0.1 and/or ::1).
We use Keycloak as the identity provider in the following examples, but the steps will be similar in other standard identity providers. If you encounter difficulties during this phase, refer to the Keycloak documentation.
- Create a confidential client
kongwithprivate_key_jwtauthentication and configure Keycloak to download the public keys from [the OpenID Connect Plugin JWKS endpoint][json-web-key-set]:
-
Create another confidential client
servicewithclient_secret_basicauthentication. For this client, Keycloak will auto-generate a secret similar to the following:cf4c655a-0622-4ce6-a0de-d3353ef0b714. Enable the client credentials grant for the client:
-
(Optional) Create another confidential client
cert-boundwith settings similar to theserviceclient created previously. From the Advanced tab, enable the OAuth 2.0 Mutual TLS Certificate Bound Access Tokens Enabled toggle. -
(Optional, to test mTLS Client Authentication) Create another confidential client
client-tls-authwith settings similar to theserviceclient created above. From the Credentials tab, select the X509 Certificate Client Authenticator and fill the Subject DN field so that it matches the Kong client certificate’s, e.g.:CN=JohnDoe, OU=IT. -
(Optional, to test Demonstrating Proof-of-Possession Client Authentication) Create another confidential client
client-dpop-authwith settings similar to theserviceclient created above. From the Advanced tab, enable theOAuth 2.0 DPoP Bound Access Tokens Enabled toggle. - Create a verified user with the name:
johnand the non-temporary password:doethat can be used with the password grant:
Alternatively you can download the exported Keycloak configuration, and use it to configure the Keycloak. Please refer to Keycloak import documentation for more information.
You need to modify Keycloak standalone.xml configuration file, and change the socket binding from:
<socket-binding name="https" port="${jboss.https.port:8443}"/>
to
<socket-binding name="https" port="${jboss.https.port:8440}"/>
The Keycloak default https port conflicts with the default Kong TLS proxy port,
and that can be a problem if both are started on the same host.
Note: The mTLS Client Authentication, along with the proof of possession feature that validates OAuth 2.0 Mutual TLS Certificate Bound Access Tokens, both require configuring Keycloak to validate client certificates with mTLS using the
--https-client-auth=requestoption, and to configure TLS appropriately, including adding the trusted client certificates to the truststore. For more information, refer to the Keycloak documentation.
Configure Kong Gateway
-
Create a service:
curl -i -X POST http://localhost:8001/services \ --data "name=openid-connect" \ --data "url=https://httpbin.konghq.com/anything" -
Create a route:
curl -i -X POST http://localhost:8001/services/openid-connect/routes \ --data "name=openid-connect" \ --data "paths[]=/"
Set up the refresh token grant
The following examples are built with simplicity in mind, and are not meant for a production environment. Because
httpbin.konghq.comis the upstream service in these examples, we highly recommended that you do not run these examples with a production identity provider as there is a high chance of leaking information. The examples also use the plain HTTP protocol, which you should never use in production.
Using the Keycloak and Kong Gateway configuration from the prerequisites, set up an instance of the OpenID Connect plugin with a refresh token grant.
For the demo, we’re going to set up the following:
- Issuer, client ID, and client auth: settings that connect the plugin to your IdP (in this case, the sample Keycloak app).
- Auth method: you only need the refresh token grant for this flow. For the purposes of the demo, the example also enables the password grant.
- We want to only search headers for the refresh token.
With all of the above in mind, let’s test out the refresh token grant with Keycloak.
Enable the OpenID Connect plugin on the openid-connect service:
Test the refresh token grant
Get a refresh token
In this example, the password grant
and the upstream_refresh_token_header are enabled for demoing purposes.
One way to get a refresh token is to issue the following call
(we use jq to filter the response):
curl --user john:doe http://localhost:8000 | jq -r '.headers."Refresh-Token"'
You can use the output from the Refresh-Token header:
<refresh-token>
Access a service with the token
Request the service with a refresh token:
curl http://localhost:8000 \
--header "Refresh-Token:$(curl --user john:doe http://localhost:8000 | \
jq -r '.headers."Refresh-Token"')"
or
curl http://localhost:8000 \
--header "Refresh-Token: <refresh-token>"
You should get an HTTP 200 response with a refresh token header:
GET / HTTP/1.1
Refresh-Token: <refresh-token>