Step 3: Implement Authorization Flow
Last updated
Last updated
Now it's time to implement the OAuth 2.0 authorization flow.
IMPORTANT: Authorization requirements depend on your client type:
Confidential Clients (Server-side): JAR (JWT-Secured Authorization Request) is REQUIRED
Public Clients (SPAs/Mobile): PKCE is REQUIRED, JAR is FORBIDDEN
📖 Need context? Check the Integration Flow Overview to see how this step fits into the complete process.
In this step, you will learn:
For Confidential Clients (Server-side applications):
Create JAR (JWT-Secured Authorization Request) - REQUIRED
Sign authorization parameters in JWT format
Handle state parameter for CSRF protection
Redirect users to Oten IDP with signed requests
For Public Clients (SPAs/Mobile apps):
Implement PKCE (Proof Key for Code Exchange) - REQUIRED
Generate secure code verifier and challenge
Handle state parameter for CSRF protection
Use direct authorization parameters (NO JAR)
This diagram shows the authorization flow. The specific requirements depend on your client type:
Confidential clients (server-side applications) MUST use JAR for enhanced security. Public clients MUST NOT use JAR.
JAR (JWT Authorization Request) consists of two main parts: JWT Claims and OAuth Parameters. All OAuth parameters must be included in the JWT payload instead of URL query parameters.
Oten IDP supports two signing methods for confidential clients:
When using HS256, you use your existing client secret:
When using EdDSA, you need to generate Ed25519 key pairs:
Note: For SPAs, you'll need a backend service to create JAR since private keys cannot be stored in browsers.
Before proceeding to the callback handling, verify your implementation based on client type:
Next: Step 4: Handle Callback
📖 Public Client (SPA/Mobile)? For comprehensive PKCE implementation with complete code examples, see the PKCE Implementation Guide or PKCE without JAR Guide.

Confidential Clients: Must use JAR (JWT-Secured Authorization Request)
Public Clients: Must use PKCE with direct parameters (JAR forbidden)
Can't implement JAR? If your confidential client application cannot support JAR due to technical constraints, contact support@oten.dev to discuss alternative solutions.
iss
Issuer - Your client ID
"your-client-id"
Must match client_id
aud
Audience - Oten IDP endpoint
"https://account.oten.com"
Fixed for Oten
iat
Issued At - JWT creation time (Unix timestamp)
1672531200
Current time
exp
Expiration - JWT expiry time (Unix timestamp)
1672531500
Max 5 minutes after iat
jti
JWT ID - Unique identifier for request
"uuid-v4-string"
Prevents replay attacks
client_id
Application client ID
"your-client-id"
Must match iss
redirect_uri
Callback URL after authorization
"https://yourapp.com/callback"
Must be pre-registered
response_type
Desired response type
"code"
Always "code" for Authorization Code flow
scope
Requested access permissions
"openid profile email"
Minimum requires "openid"
state
CSRF protection parameter
"random-string-32-chars"
Protects against CSRF
code_challenge
SHA256 hash of code_verifier
"E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
Base64URL encoded
code_challenge_method
Hash method
"S256"
Always "S256"
prompt
UI display behavior
"consent"
"none", "login", "consent", "select_account"
ui_locales
Interface language
"en-US"
"vi-VN", "en-US", "ja-JP"
login_hint
Email/username hint
-
"user@example.com"
max_age
Max time since last login (seconds)
3600
0 (force re-auth), 7200
workspace_hint
Workspace ID hint
"workspace-123"
Auto-select workspace
nonce
Random value to link ID token
"random-nonce-value"
Additional security
Basic Login
Standard OAuth + PKCE
scope: "openid profile email"
Force Re-auth
Add max_age=0 + prompt=login
max_age: 0, prompt: "login"
Silent Auth
prompt=none
prompt: "none" (will fail if not logged in)
Multi-language
ui_locales
ui_locales: "vi-VN en-US"
Workspace App
workspace_hint
workspace_hint: "workspace-123"
High Security
Short expiry + nonce
exp: now + 60, nonce: "random"
❌ Don't send parameters in URL query - Oten will reject them for confidential clients
❌ Don't use unsupported algorithms - Only HS256 and EdDSA are supported
❌ Don't forget kid in JWT header for EdDSA - Must match your JWKS
❌ Don't make JAR expire too long - 5 minutes maximum recommended
❌ Don't store private keys in client-side code - Use backend for SPAs
❌ Don't use RSA keys - Oten only supports HS256 and EdDSA
❌ Don't reuse JTI values - Each JAR must have unique identifier
❌ Don't include sensitive data - JAR is base64 encoded, not encrypted
❌ Don't use JAR - JAR is forbidden for public clients
❌ Don't use weak code verifiers - Must be 128 characters with sufficient entropy
❌ Don't store code verifier insecurely - Use sessionStorage (SPA) or Keychain/Keystore (mobile)
❌ Don't skip state validation - Always validate state parameter to prevent CSRF
❌ Don't use HTTP - HTTPS is required for all OAuth flows
❌ Don't include client_secret - Public clients must not use client secrets