OAuth 2.0 và OpenID Connect
OAuth 2.0 là framework delegated authorization; OpenID Connect thêm identity/authentication layer. Token type, client type, redirect boundary và validation phải khớp với flow thực tế.
1. Roles và registration
Resource owner là người/đơn vị sở hữu dữ liệu; client yêu cầu quyền; authorization server xác thực và cấp grant/token; resource server bảo vệ API. Registration phải ràng buộc client type, exact redirect URI, allowed grants, credentials, scopes và logout/redirect policy.
| Client | Đặc điểm | Flow phù hợp |
|---|---|---|
| Confidential server | Giữ được secret ở backend | Authorization Code; client credentials cho machine identity |
| Public SPA/mobile | Không giữ secret an toàn trong browser/device | Authorization Code + PKCE |
| Service-to-service | Không đại diện user | Client Credentials, scope least privilege |
2. Authorization Code + PKCE
Client tạo random verifier và challenge, lưu state/nonce, redirect user tới authorization endpoint. Authorization server redirect về exact registered URI với code; client gửi code + verifier tới token endpoint. PKCE giảm code interception; state bind request/response chống CSRF; OIDC nonce bind ID token với auth request và giúp phát hiện replay.
verifier = randomHighEntropy()
challenge = BASE64URL(SHA256(verifier))
authorize?response_type=code&code_challenge=challenge&state=state
token(code, code_verifier=verifier) -> access_token + id_token
- Không dùng wildcard hoặc open redirect; compare exact scheme/host/path/port theo registration.
- State/nonce phải unique, expire và được bind đúng browser session.
- PKCE không thay thế redirect validation, token validation hoặc CSRF defense.
3. Token roles và validation
Access token có thể opaque hoặc JWT và chỉ resource server cần hiểu. Refresh token đổi access token mới; ID token chứa authentication claims cho OIDC client. Client validate ID token issuer, audience/azp, signature, expiry và nonce. Resource server validate access token issuer, audience, signature, time và scope/claims.
Discovery metadata/JWKS chỉ lấy từ trusted configured issuer; không để token/header điều khiển URL fetch để tránh mix-up/SSRF. Algorithm allow-list và key trust boundary phải được cấu hình rõ.
4. Client Credentials
Flow này đại diện machine client, không đại diện user. Credentials/key chỉ nằm server-side, được rotate và giới hạn scope. Không dùng client credentials cho SPA/mobile vì secret trong public client không còn là secret.
5. Refresh rotation và compromise
Public client nên dùng refresh-token rotation: mỗi lần refresh cấp token mới, token cũ reuse là tín hiệu compromise để revoke token family. Storage cần bảo vệ, idle/absolute lifetime, logout/revocation endpoint và telemetry theo provider. Bearer token bị đánh cắp có thể dùng tới expiry; sender-constrained mTLS/DPoP giảm rủi ro tùy ecosystem.
6. Browser architecture và checklist
BFF có thể giữ access/refresh token ở server, browser chỉ giữ session cookie; trade-off là state/scale và CSRF cần thiết kế. Nếu token ở JS, XSS có thể đọc/đánh cắp token; CSP, dependency hygiene và short lifetime chỉ giảm tác động.
- Flow có đúng client type và PKCE không?
- Redirect URI, state, nonce và issuer có exact/trusted không?
- API phân biệt access token với ID token và kiểm tra audience/scope không?
- Refresh reuse, key rotation, revoke và incident telemetry có rõ không?