Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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 algorithm

      • Payload - 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 it

        • it 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 applications

  • tokens 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 the secret_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
            languagepy
            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
breakoutModewide
languagebash
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
languagejson
{
  "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:

...