OIDC Design

Endpoints

  • discovery endpoint(/.well-known/openid-configuration), show all endpoints for client
  • auth endpoint(/auth), trigger authorize workflow
  • token endpoint(/token), exchange/refresh token info
  • JWKS endpoint(/.well-known/jwks.json), is used to verify jwt token, such like id token
  • user endpoint(/me), get lateset user info
  • end session endpoint(/session/end), is used to logout

Token

ID Token

It’s a JWT token, represents a user credentials for successful login user,
and includes basic user profile which defined by scope and claim.

It’s always passed to client and is used show user info.

most important fields in ID Token:

  • sub(Subject), subject contains user unique id
  • iss(Issuer), IDP host which signed ID Token
  • exp(Expiration time), expiration timestamp for ID Token
  • iat(Issued at), sign timestamp for ID Token
  • aud(Audience), mostly is client id
  • user claims, show basic user info
1
2
3
4
5
6
7
8
9
{
"iss": "https://idp-doamin",
"sub": "24400320",
"aud": "client-id",
"exp": 1311281970,
"iat": 1311280970,
...
<user claims>
}

Client uses HTTP Header Authorization: "Bearer <ID Token>" to send request to server,
then server could use JWKS endpoint to get public key to verify ID Token.

Access Token

It mostly is an Opaque token which is a random string
and used to access IDP resources, such like below cases:

  • invoke user endpoint to get more user details.

Access token is mostly saved in backend. If client required IDP resources, backend service could be proxy to get related resources and return to client.

Refresh Token

It’s used to get a new Access Token and ID Token when Access Token / ID Token is expired by invoking token endpoint.

It should be saved in backend for security.

It requires scope offline_access and prompt=consent in querystring when trigger auth workflow,
and use grant type refresh_token when refresh token with token endpoint

More details for reference:

Expiration Time for Tokens

Refresh Token > ID Token >= Access Token

When ID Token/Access Token is expired, client can trigger refresh token action in server to get new one,
that’s why expiration time for ID Token/Access Token could be short.

When Refresh Token is expired, user must re-login again to obtain new token info include refresh token,
to avoid requiring users to login frequently, refresh tokens are given a long expiration time.

authorize Workflow with authorization_code

good resources for reference:

Client Integration

Preparation:

  • client id/client secret, presents client is trusted source
  • login callback
  • logout callback
  • scope
  • grand type

Login and get Id Token

  1. Client backend generates IDP login url for client frontend
  2. Frontend redirects to IDP auth endpoint by generated login url
  3. When login success, IDP will redirect frontend to login callback page with code
  4. Frontend will transfer code to backend, then backend will exchange token by code with IDP token endpoint
  5. Backend return id token to frontend after token exchange.
  6. Show user info from id token

Logout

  1. Client backend generate IDP logout url for frontend
  2. Frontend redirects to IDP end session endpoint by generated logout url
  3. When logout success, IDP will redirect frontend to logout callback page
  4. Clear token in frontend/backend session
  5. Frontend redirects to root page

Verify Id Token

  1. Client frontend uses HTTP Header Authorization: "Bearer <ID Token>" to send request to backend,
  2. Backend will use JWKS endpoint to get public key to verify ID Token
  3. If invalid, request will be denied with http status 401 Unauthorized frontend should re-login.

Refresh Expired Id Token

  1. Check if Id Token is expired periodly or when sending request with id token
  2. If expired, client frontend apply to refresh Id Token with backend
  3. Backend will invoke token endpoint to get new Token info, include access token and id token.
  4. Backend update token in session, then return new id token to frontend
  5. Frontend save id token and update user info

SPA Integration

It recommends use authorization_code + PKCE flow for SPA, because it has no backend.

More details please refer:

Refresg Id Token in SPA

Refresh with refresh token

It requires store refresh token in frontend, and it’s a security risk.

Mostly it requires OIDC IDP to support refresh token with rotation and expiring old refresh token,
then there will no security risk.

It’s recommended by using refresh token with rotation.

Silent Authentication

It uses a hidden <iframe> that sends a new authorization request to OIDC IDP with prompt=none.

It requires:

  • user session should be alive in OIDC IDP
  • prompt=none is supported by OIDC IDP for this client
  • silent callback url in redirect_uri of registered client in OIDC IDP

Mostly use 3rd part library, such as oidc-client-ts, instead of implement by youself.

OIDC IDP Model Design

TODO

Reference