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 | { |
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:
- demo show in 使用 OIDC 授权码模式
Client Integration
Preparation:
- client id/client secret, presents client is trusted source
- login callback
- logout callback
- scope
- grand type
Login and get Id Token
- Client backend generates IDP login url for client frontend
- Frontend redirects to IDP
auth endpoint
by generated login url - When login success, IDP will redirect frontend to
login callback
page with code - Frontend will transfer code to backend, then backend will exchange token by code with IDP
token endpoint
- Backend return id token to frontend after token exchange.
- Show user info from id token
Logout
- Client backend generate IDP logout url for frontend
- Frontend redirects to IDP
end session endpoint
by generated logout url - When logout success, IDP will redirect frontend to
logout callback
page - Clear token in frontend/backend session
- Frontend redirects to root page
Verify Id Token
- Client frontend uses HTTP Header
Authorization: "Bearer <ID Token>"
to send request to backend, - Backend will use
JWKS endpoint
to get public key to verify ID Token - If invalid, request will be denied with http status 401 Unauthorized frontend should re-login.
Refresh Expired Id Token
- Check if Id Token is expired periodly or when sending request with id token
- If expired, client frontend apply to refresh Id Token with backend
- Backend will invoke
token endpoint
to get new Token info, include access token and id token. - Backend update token in session, then return new id token to frontend
- 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 clientsilent 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