Step 1: Choose OAuth Library
The first step in integrating Oten IDP is selecting the right OAuth 2.0 / OpenID Connect library for your technology stack. IMPORTANT: Your chosen library must support JAR (JWT-Secured Authorization Request) as Oten IDP requires it for all authorization requests.
Can't implement JAR? If your application cannot support JAR due to technical constraints, contact [email protected] to discuss enabling traditional OAuth flow as a temporary solution.
📖 Need the big picture? Check out the Integration Flow Overview to understand how this step fits into the complete process.
🎯 What You'll Learn
In this step, you will:
Understand JAR (JWT-Secured Authorization Request) requirements
Choose libraries that support JAR and JWT signing
Install and configure your chosen library with JAR support
Understand the trade-offs between different options
🚨 JAR Requirement - CRITICAL
Oten IDP requires JAR (JWT-Secured Authorization Request) for ALL authorization requests. Your chosen library must support:
Required JAR Features
✅ JWT Creation and Signing (RS256, HS256, or EdDSA)
✅ Custom JWT Claims (ability to add OAuth parameters to JWT payload)
✅ Key Management (RSA keys for RS256 or client secret for HS256)
✅ Request Parameter Support (sending JWT in
requestparameter)
❌ Libraries That Won't Work
Libraries that only support traditional OAuth query parameters will NOT work with Oten IDP:
// ❌ This approach will be REJECTED by Oten IDP
const authURL = `https://account.oten.com/v1/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectURI}&response_type=code&scope=openid profile email&state=${state}`;✅ What You Need
Libraries that can create signed JWTs and send them in the request parameter:
// ✅ This is the ONLY way that works with Oten IDP
const requestJWT = await createJAR(authParams, privateKey);
const authURL = `https://account.oten.com/v1/oauth/authorize?client_id=${clientId}&request=${requestJWT}`;📚 Library Categories
Official vs Third-Party Libraries
Official Libraries
Maintained by platform vendors (Google, Microsoft, etc.)
Well-documented and supported
Regular security updates
Best practices built-in
May need custom JAR implementation
Third-Party Libraries
Community-maintained
Often more flexible
May have additional features
Varying quality and support levels
Check JAR support before choosing
Oten Official Libraries
Specifically designed for Oten IDP
Built-in JAR support
Optimized for Oten features
Direct support from Oten team
Client Type Considerations
Confidential Clients (Server-Side)
Can securely store client secrets
Token exchange happens on server
More security options available
Examples: Web servers, APIs, backend services
Public Clients (Client-Side)
Cannot store secrets securely
Must use PKCE for security
Tokens handled in browser/device
Examples: SPAs, mobile apps, desktop apps
🛠️ Technology-Specific Recommendations
JavaScript/Node.js
For Server-Side (Node.js)
# Recommended: openid-client
npm install openid-client
# Alternative: passport with OAuth strategy
npm install passport passport-oauth2openid-client - Most comprehensive
const { Issuer } = require('openid-client');
// Discover Oten configuration
const otenIssuer = await Issuer.discover('https://account.oten.com');
const client = new otenIssuer.Client({
client_id: 'your-client-id',
client_secret: 'your-client-secret',
redirect_uris: ['https://yourapp.com/callback'],
response_types: ['code'],
});For Client-Side (Browser/SPA)
# Recommended: oidc-client-ts
npm install oidc-client-ts
# Alternative: auth0-spa-js (more opinionated)
npm install @auth0/auth0-spa-jsoidc-client-ts - Standards compliant
import { UserManager } from 'oidc-client-ts';
const userManager = new UserManager({
authority: 'https://account.oten.com',
client_id: 'your-client-id',
redirect_uri: 'https://yourapp.com/callback',
response_type: 'code',
scope: 'openid profile email',
post_logout_redirect_uri: 'https://yourapp.com',
});Python
Recommended Libraries
# Most comprehensive: authlib
pip install authlib
# Alternative: requests-oauthlib
pip install requests-oauthlib
# For Django: django-oauth-toolkit
pip install django-oauth-toolkit
# For Flask: flask-oauthlib
pip install flask-oauthlibAuthlib - Modern and comprehensive
from authlib.integrations.flask_client import OAuth
oauth = OAuth(app)
oten = oauth.register(
name='oten',
client_id='your-client-id',
client_secret='your-client-secret',
server_metadata_url='https://account.oten.com/.well-known/openid_configuration',
client_kwargs={
'scope': 'openid profile email'
}
)Java
Spring Boot (Recommended)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>Spring Security OAuth2
# application.yml
spring:
security:
oauth2:
client:
registration:
oten:
client-id: your-client-id
client-secret: your-client-secret
scope: openid,profile,email
authorization-grant-type: authorization_code
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
provider:
oten:
authorization-uri: https://account.oten.com/v1/oauth/authorize
token-uri: https://account.oten.com/v1/oauth/token
user-info-uri: https://account.oten.com/v1/oauth/userinfo
jwk-set-uri: https://account.oten.com/.well-known/jwks.jsonAlternative: pac4j
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-oidc</artifactId>
<version>5.7.0</version>
</dependency>C#/.NET
ASP.NET Core (Recommended)
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnectOpenID Connect Authentication
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.Authority = "https://account.oten.com";
options.ClientId = "your-client-id";
options.ClientSecret = "your-client-secret";
options.ResponseType = "code";
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("email");
options.CallbackPath = "/signin-oidc";
});PHP
Recommended Libraries
# Most popular: league/oauth2-client
composer require league/oauth2-client
# Alternative: thephpleague/oauth2-client
composer require thephpleague/oauth2-client
# For Laravel: laravel/socialite
composer require laravel/socialiteLeague OAuth2 Client
use League\OAuth2\Client\Provider\GenericProvider;
$provider = new GenericProvider([
'clientId' => 'your-client-id',
'clientSecret' => 'your-client-secret',
'redirectUri' => 'https://yourapp.com/callback',
'urlAuthorize' => 'https://account.oten.com/v1/oauth/authorize',
'urlAccessToken' => 'https://account.oten.com/v1/oauth/token',
'urlResourceOwnerDetails' => 'https://account.oten.com/v1/oauth/userinfo',
]);Go
Oten Official Library (Recommended)
# Oten go-oauth library with built-in JAR support
go get gitlab.oten.com/go-sdk/go-oauth/clientOten go-oauth - Official library with JAR support
import (
"gitlab.oten.com/go-sdk/go-oauth/client"
"gitlab.oten.com/go-sdk/go-oauth/jar"
)
// Initialize OAuth client with JAR support
config := &client.Config{
ClientID: "your-client-id",
ClientSecret: "your-client-secret", // Optional for public clients
Endpoint: client.OtenEndpoint("https://account.oten.com"),
RedirectURL: "https://yourapp.com/callback",
Scopes: []string{"openid", "profile", "email"},
// JAR configuration (REQUIRED for Oten IDP)
JARConfig: &jar.Config{
SigningMethod: jar.RS256, // or jar.HS256
PrivateKey: loadPrivateKey(), // RSA private key for RS256
KeyID: "your-key-id", // Key ID from your JWKS
Issuer: "your-client-id", // Usually your client ID
Audience: "https://account.oten.com",
},
}
// Create OAuth client
oauthClient := client.New(config)
// Generate authorization URL with JAR
authURL, err := oauthClient.AuthCodeURL("state-value", client.AccessTypeOffline)
if err != nil {
log.Fatal(err)
}
// The library automatically creates JAR and sends it in request parameter
fmt.Println("Authorization URL:", authURL)Key Features of Oten go-oauth:
✅ Built-in JAR Support: Automatically creates and signs JWT authorization requests
✅ Multiple Signing Methods: Supports RS256 (RSA) and HS256 (HMAC) algorithms
✅ PKCE Integration: Automatic PKCE generation for public clients
✅ Token Management: Built-in token refresh and validation
✅ JWKS Support: Automatic public key publishing
✅ Oten Optimized: Designed specifically for Oten IDP features
Alternative: Standard Library (Requires Custom JAR Implementation)
# Standard OAuth2 library (you'll need to implement JAR manually)
go get golang.org/x/oauth2
go get github.com/golang-jwt/jwt/v5 # For JWT creationManual JAR Implementation with Standard Library
import (
"golang.org/x/oauth2"
"github.com/golang-jwt/jwt/v5"
)
// You'll need to implement JAR creation manually
func createJAR(authParams map[string]interface{}, privateKey interface{}) (string, error) {
now := time.Now()
claims := jwt.MapClaims{
// Standard JWT claims
"iss": authParams["client_id"],
"aud": "https://account.oten.com",
"iat": now.Unix(),
"exp": now.Add(5 * time.Minute).Unix(),
"jti": generateUUID(),
// OAuth parameters
"client_id": authParams["client_id"],
"redirect_uri": authParams["redirect_uri"],
"response_type": authParams["response_type"],
"scope": authParams["scope"],
"state": authParams["state"],
"code_challenge": authParams["code_challenge"],
"code_challenge_method": authParams["code_challenge_method"],
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
token.Header["kid"] = "your-key-id"
return token.SignedString(privateKey)
}
// Standard OAuth2 config (without JAR support)
config := &oauth2.Config{
ClientID: "your-client-id",
ClientSecret: "your-client-secret",
Endpoint: oauth2.Endpoint{
AuthURL: "https://account.oten.com/v1/oauth/authorize",
TokenURL: "https://account.oten.com/v1/oauth/token",
},
RedirectURL: "https://yourapp.com/callback",
Scopes: []string{"openid", "profile", "email"},
}
// You'll need to manually create JAR and modify the auth URL
authParams := map[string]interface{}{
"client_id": config.ClientID,
"redirect_uri": config.RedirectURL,
"response_type": "code",
"scope": strings.Join(config.Scopes, " "),
"state": "your-state",
"code_challenge": "your-code-challenge",
"code_challenge_method": "S256",
}
requestJWT, err := createJAR(authParams, privateKey)
if err != nil {
log.Fatal(err)
}
// Create authorization URL with JAR
authURL := fmt.Sprintf("%s?client_id=%s&request=%s",
config.Endpoint.AuthURL,
config.ClientID,
requestJWT)Recommendation: Use the Oten go-oauth library as it handles all JAR complexity automatically and is specifically designed for Oten IDP.
Oten go-oauth Library Details
The Oten go-oauth library provides comprehensive OAuth 2.0 and OpenID Connect support with built-in JAR functionality:
Installation:
go get gitlab.oten.com/go-sdk/go-oauth/clientKey Components:
clientpackage: Main OAuth client with JAR supportjarpackage: JWT-Secured Authorization Request implementationtokenpackage: Token management and validationjwkspackage: JSON Web Key Set handling
Complete Example:
package main
import (
"context"
"fmt"
"log"
"gitlab.oten.com/go-sdk/go-oauth/client"
"gitlab.oten.com/go-sdk/go-oauth/jar"
)
func main() {
// Load your RSA private key
privateKey, err := loadRSAPrivateKey("jar-private-key.pem")
if err != nil {
log.Fatal(err)
}
// Configure OAuth client with JAR
config := &client.Config{
ClientID: "your-client-id",
RedirectURL: "https://yourapp.com/callback",
Scopes: []string{"openid", "profile", "email"},
Endpoint: client.OtenEndpoint("https://account.oten.com"),
// JAR configuration (automatically handled)
JARConfig: &jar.Config{
SigningMethod: jar.RS256,
PrivateKey: privateKey,
KeyID: "your-key-id",
Issuer: "your-client-id",
Audience: "https://account.oten.com",
},
}
// Create OAuth client
oauthClient := client.New(config)
// Generate authorization URL (JAR is automatically created)
authURL, err := oauthClient.AuthCodeURL("random-state", client.AccessTypeOffline)
if err != nil {
log.Fatal(err)
}
fmt.Println("Visit this URL:", authURL)
// Handle callback (after user authentication)
// code := "authorization-code-from-callback"
// token, err := oauthClient.Exchange(context.Background(), code)
// if err != nil {
// log.Fatal(err)
// }
// fmt.Printf("Access Token: %s\n", token.AccessToken)
}Advanced Features:
// Custom JAR claims
jarConfig := &jar.Config{
SigningMethod: jar.RS256,
PrivateKey: privateKey,
KeyID: "your-key-id",
Issuer: "your-client-id",
Audience: "https://account.oten.com",
// Custom claims
CustomClaims: map[string]interface{}{
"ui_locales": "en-US",
"prompt": "consent",
"workspace_hint": "workspace-123",
},
}
// PKCE support for public clients
config := &client.Config{
ClientID: "your-public-client-id",
RedirectURL: "https://yourapp.com/callback",
Scopes: []string{"openid", "profile", "email"},
Endpoint: client.OtenEndpoint("https://account.oten.com"),
// Enable PKCE for public clients
UsePKCE: true,
JARConfig: jarConfig,
}Ruby
Recommended Libraries
# Most comprehensive: omniauth
gem install omniauth omniauth-oauth2
# Alternative: oauth2 gem
gem install oauth2
# For Rails: omniauth-rails_csrf_protection
gem install omniauth-rails_csrf_protectionOmniAuth
Rails.application.config.middleware.use OmniAuth::Builder do
provider :oauth2, 'your-client-id', 'your-client-secret',
client_options: {
site: 'https://account.oten.com',
authorize_url: '/v1/oauth/authorize',
token_url: '/v1/oauth/token'
}
end🔍 Library Selection Criteria
JAR Support (CRITICAL for Oten IDP)
MUST HAVE features for Oten IDP integration:
✅ JWT Creation and Signing (RS256, HS256, or EdDSA algorithms)
✅ Custom JWT Claims (ability to embed OAuth parameters in JWT payload)
✅ Request Parameter Support (sending JWT in
requestparameter)✅ Key Management (RSA private keys or client secrets)
✅ JWKS Integration (for public key distribution)
Security Features
Look for libraries that support:
JAR (JWT-Secured Authorization Request) - REQUIRED for Oten
PKCE (essential for public clients)
State parameter validation (CSRF protection)
Nonce support (replay attack prevention)
JWT validation (signature verification)
Token refresh (automatic renewal)
Standards Compliance
Ensure the library supports:
JAR RFC 9101 - CRITICAL for Oten IDP
OAuth 2.0 RFC 6749
OpenID Connect Core 1.0
PKCE RFC 7636 (for public clients)
JWT RFC 7519
JWKS RFC 7517 (for key distribution)
Oten Specific Features
Preferred libraries should support:
Oten endpoints (pre-configured)
Multi-tenant workspace selection
Oten specific scopes
Built-in error handling for Oten responses
Maintenance and Support
Consider:
Active development (recent commits)
Security updates (vulnerability patches)
Documentation quality
Community support
Issue response time
Oten compatibility (if available)
📦 Installation Examples
Package Managers
npm (Node.js)
# Install with npm
npm install openid-client
# Install with yarn
yarn add openid-client
# Install with pnpm
pnpm add openid-clientpip (Python)
# Install with pip
pip install authlib
# Install with pipenv
pipenv install authlib
# Install with poetry
poetry add authlibMaven (Java)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<version>2.7.0</version>
</dependency>NuGet (.NET)
# Package Manager Console
Install-Package Microsoft.AspNetCore.Authentication.OpenIdConnect
# .NET CLI
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect⚙️ Configuration Basics
Environment Variables
Set up your configuration securely:
# .env file (never commit to version control)
OTEN_CLIENT_ID=your_client_id_here
OTEN_CLIENT_SECRET=your_client_secret_here
OTEN_REDIRECT_URI=https://yourapp.com/callback
# JAR Configuration (REQUIRED for Oten IDP)
JAR_PRIVATE_KEY_PATH=./jar-private-key.pem
JAR_KEY_ID=your-key-id
JWKS_URI=https://yourapp.com/.well-known/jwks.jsonBasic Configuration Structure with JAR
Most libraries need to be configured for JAR support:
const config = {
// Client credentials
clientId: process.env.OTEN_CLIENT_ID,
clientSecret: process.env.OTEN_CLIENT_SECRET, // Optional for public clients
// Endpoints
authorizationURL: 'https://account.oten.com/v1/oauth/authorize',
tokenURL: 'https://account.oten.com/v1/oauth/token',
// Application settings
redirectURI: process.env.OTEN_REDIRECT_URI,
scope: ['openid', 'profile', 'email'],
// Security settings
responseType: 'code',
grantType: 'authorization_code',
// JAR Configuration (REQUIRED for Oten IDP)
jar: {
enabled: true, // JAR is mandatory
signingMethod: 'RS256', // or 'HS256'
privateKeyPath: process.env.JAR_PRIVATE_KEY_PATH,
keyId: process.env.JAR_KEY_ID,
issuer: process.env.OTEN_CLIENT_ID, // Usually your client ID
audience: 'https://account.oten.com'
}
};JAR-Specific Configuration
Since Oten IDP requires JAR, you'll need additional setup:
// Example for libraries that support JAR
const jarConfig = {
// JWT signing configuration
algorithm: 'RS256', // Recommended: RS256 with RSA keys
privateKey: fs.readFileSync(process.env.JAR_PRIVATE_KEY_PATH),
keyId: process.env.JAR_KEY_ID,
// JWT claims
issuer: process.env.OTEN_CLIENT_ID,
audience: 'https://account.oten.com',
expirationTime: 300, // 5 minutes (recommended)
// JWKS endpoint for public key distribution
jwksUri: process.env.JWKS_URI
};🔧 Testing Your Library Choice
Quick Test Setup for JAR Support
Install the library
Set up JAR configuration (private key, JWKS endpoint)
Create a simple JAR authorization request
Test the JWT creation and signing
Verify the authorization URL format
Test the complete OAuth flow
JAR Testing Checklist
General Validation Checklist
Test JAR Implementation
// Quick test to verify JAR capability
async function testJARSupport() {
try {
// Test JWT creation
const authParams = {
client_id: 'test-client',
redirect_uri: 'https://test.com/callback',
response_type: 'code',
scope: 'openid profile email',
state: 'test-state'
};
const requestJWT = await createJAR(authParams);
console.log('✅ JAR creation successful');
// Test authorization URL format
const authURL = `https://account.oten.com/v1/oauth/authorize?client_id=test-client&request=${requestJWT}`;
console.log('✅ Authorization URL format correct');
return true;
} catch (error) {
console.error('❌ JAR test failed:', error);
return false;
}
}🧭 Navigation
← Previous: JAR Requirement - Understanding JAR requirements
↑ Overview: Integration Flow Overview - See the big picture
→ Next: Step 2: Configure OAuth Client - Set up your OAuth client
Progress: Step 1 of 5 complete ✅
Last updated