...
The access_token
& refresh_token
will be used to grant access to clients
The tokens are JWT tokens
JWT tokens allow systems to encode a JSON object into the token itself, which can be decoded by the application to retrieve user information (email, username, roles, etc.)
JWT tokens are separated into 3 sections:
Header
- info on encode algorithmPayload
- user info (email, username, roles, etc.)Signature
- created by taking the encoded header, the encoded payload, a secret, the algorithm specified in the header, and signing itit will ensure if the token has been tampered with (and ultimately reject the token)
...
one set of tokens (
access_token
,refresh_token
) can be re-used by multiple applicationstokens can be decoded and the payload can be read to ensure role-based access to REST API endpoints
According to OpenID Connect standards, user info can be retrieved in 2 ways:
online method, making a request to the provider’s UserInfo endpoint
curl https://[provider endpoint]/.../protocol/openid-connect/userinfo
reliable but can increase latency of having to make additional requests to retrieving user info every time your service is being called (not scalable in the long run)
decoding JWT token
the user info is encoded in the token and can be retrieved without having to make additional requests (more scalable)
requirements:
if using the
HS256
algorithm, tokens can be encoded and decoded with thesecret_key
not secure. if the
secret_key
gets leaked users can create their own JWT tokens and can potentially have “superuser” access to your system
if using the
RS256
algorithm (more secure):tokens will be encoded with a
private_key
tokens will be decoded with a
public_key
Code Block language py import json from authlib.jose import jwt public_key = """ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi2W0DkV... -----END PUBLIC KEY----- """ token = 'eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ0czA0c...' claims = jwt.decode(token, public_key) claims.validate() # will raise error if token expired
Example of JWT token:
...
According to the OpenID Connect documentation when your access_token
expires you can use the refresh_token
to retrieve a new token (add client_secret
for if client type is confidential
)
ex (with Keycloak
):
Code Block | ||||
---|---|---|---|---|
| ||||
curl -s -X POST \
-d client_id=<client_id> \
-d client_secret=<client_secret> \
-d grant_type=refresh_token \
-d refresh_token=<refresh_token> \
"http://localhost:8080/auth/realms/<realm>/protocol/openid-connect/token" | python -m json.tool |
response:
Code Block | ||
---|---|---|
| ||
{
"access_token": "eyJhbGciOiJSUzI1NiIsIn...",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI...",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "183ebafb-93ed-408f-a2ea-3708f518a694",
"scope": "profile"
} |
There are multiple SSO providers that use OpenID Connect for A&A:
...