Django client for Onehux Accounts SSO/SLO integration
Project description
Onehux SSO Client for Django
Official Django client library for integrating with Onehux Accounts - A production-ready OAuth2/OIDC Identity Provider with SSO/SLO support.
Features
- ✅ OAuth2/OIDC Authentication - Complete authorization code flow with PKCE
- ✅ Single Sign-On (SSO) - Seamless login across multiple applications
- ✅ Single Logout (SLO) - Logout from all connected applications
- ✅ Token Management - Automatic token refresh and validation
- ✅ User Synchronization - Real-time user profile updates via webhooks
- ✅ Django Integration - Middleware, authentication backend, and decorators
- ✅ Type Hints - Full type annotations for better IDE support
- ✅ Production Ready - Battle-tested and secure
Quick Start
1. Install the package
pip install onehux-sso-client
2. Configure settings.py
INSTALLED_APPS = [
'onehux_sso_client',
'accounts', # Your app with User model
...
]
AUTH_USER_MODEL = 'accounts.User'
3. Create your User model
You have four ways you can create your user models to work with this package
Option 1: Mixin (Recommended)
# myproject/models.py
from django.contrib.auth.models import AbstractUser
from sso_client.models import OnehuxSSOUserMixin
class User(OnehuxSSOUserMixin, AbstractUser):
"""Custom user with SSO support + your own fields"""
department = models.CharField(max_length=100)
employee_id = models.CharField(max_length=20)
class Meta:
db_table = 'users'
Option 2: Minimal Integration For users who just want SSO without profile sync:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
onehux_user_id = models.UUIDField(unique=True, null=True)
# You handle profile sync yourself
Option 3: Use management command (easiest)
python manage.py onehux_init --app=accounts
Option 4: Copy template manually
Download the user_model_template.py
and save it as accounts/models.py.
Option 5: Copy from installed package
cp $(python -c "import onehux_sso_client; print(onehux_sso_client.__path__[0])")/templates/user_model_template.py accounts/models.py
4. Run migrations
python manage.py makemigrations
python manage.py migrate
5. Add onehux configuration to your settings.py
# Onehux SSO Configuration
ONEHUX_SSO = {
'CLIENT_ID': env('CLIENT_ID'),
'CLIENT_SECRET': env('CLIENT_SECRET'),
'REDIRECT_URI': env('REDIRECT_URI'), # http://client.onehux.com/sso/callback/
# IdP Endpoints
'AUTHORIZATION_URL': env('AUTHORIZATION_URL'), # http://accounts.onehux.com/sso/authorize/
'TOKEN_URL': env('TOKEN_URL'), # http://accounts.onehux.com/sso/token/
'USERINFO_URL': env('USERINFO_URL'), # http://accounts.onehux.com/sso/userinfo/
'LOGOUT_URL': env('LOGOUT_URL'), # http://accounts.onehux.com/sso/logout/
'JWKS_URL': env('JWKS_URL'), # http://accounts.onehux.com/sso/.well-known/jwks.json
# Security
'USE_PKCE': True, # Highly recommended
'VERIFY_SSL': False, # Set to True in production
# Scopes
'SCOPES': 'openid profile email',
# Token Management
'TOKEN_REFRESH_THRESHOLD': 300, # Refresh 5 minutes before expiry
# Webhook
'WEBHOOK_SECRET': env('WEBHOOK_SECRET'),
'WEBHOOK_ENDPOINT': '/sso/api/webhooks/onehux/',
}
# ============================================================================
# PUBLIC PATHS CONFIGURATION (CRITICAL FOR SAAS)
# ============================================================================
# Define which paths are accessible WITHOUT authentication
# The SilentSSOMiddleware will NOT run on these paths
SSO_PUBLIC_PATHS = [
# Core Public Pages
'/', # Homepage
'/about/',
'/pricing/',
'/features/',
'/contact/',
'/faq/',
# Content Pages
'/blog/',
'/docs/',
'/help/',
'/support/',
# Legal Pages
'/legal/',
'/privacy/',
'/terms/',
'/cookies/',
# Authentication Pages (if you have native login)
'/signup/',
'/login/',
'/forgot-password/',
'/reset-password/',
# Public API Endpoints
'/api/public/',
'/api/docs/',
# Health Checks
'/health/',
'/status/',
]
# ============================================================================
# SILENT SSO CONFIGURATION
# ============================================================================
# Enable/disable silent SSO (auto-login if IdP session exists)
SSO_SILENT_AUTH_ENABLED = True
# Additional paths to ignore for silent SSO (beyond public paths)
# Use this for monitoring endpoints, admin pages, etc.
# Optional : Additional paths to ignore for silent SSO (beyond public paths)
SSO_SILENT_AUTH_IGNORED_PATHS = [
'/health/',
'/metrics/',
'/monitoring/',
'/health/'
]
# Optional : Paths to exclude from token refresh checks
SSO_TOKEN_REFRESH_EXCLUDED_PATHS = [
'/health/',
'/metrics/',
]
# ============================================================================
# TOKEN REFRESH CONFIGURATION
# ============================================================================
# Paths to exclude from token refresh checks
SSO_TOKEN_REFRESH_EXCLUDED_PATHS = [
'/health/',
'/metrics/',
'/monitoring/',
]
# ============================================================================
# MIDDLEWARE CONFIGURATION
# ============================================================================
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# =========================================================================
# ONEHUX SSO MIDDLEWARES (Order matters!)
# =========================================================================
# 1. Silent SSO - tries to auto-login anonymous users on protected pages
'onehux_sso_client.middleware.SilentSSOMiddleware',
# 2. Token Refresh - auto-refreshes expired tokens for authenticated users
'onehux_sso_client.middleware.SSOTokenRefreshMiddleware',
]
# ============================================================================
# AUTHENTICATION CONFIGURATION
# ============================================================================
# Custom authentication backend for SSO
AUTHENTICATION_BACKENDS = [
'onehux_sso_client.backends.OnehuxSSOBackend', # SSO authentication
'django.contrib.auth.backends.ModelBackend', # Fallback (superuser)
]
# Custom user model (if using OnehuxSSOUserMixin)
AUTH_USER_MODEL = 'accounts.User'
# Login/Logout URLs
# Where `login_required` / `@login_required` should redirect
# when an anonymous user hits a protected page
LOGIN_URL = 'sso:sso_login' # Redirect to SSO login
# Where to send the user after they click “log out”
LOGOUT_REDIRECT_URL = '/'
# Where to send the user after a *successful* login
LOGIN_REDIRECT_URL = 'accounts:dashboard' # or '/dashboard/'
# Session Configuration
SESSION_COOKIE_AGE = 86400 # 24 hours
SESSION_SAVE_EVERY_REQUEST = False
SESSION_COOKIE_SECURE = False # Set to True in production (HTTPS only)
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
# ============================================================================
# ADMIN CONFIGURATION
# ============================================================================
# Custom admin URL (for security)
ADMIN_URL = env('ADMIN_URL', default='a6b9c3d0e2f5g8h1i4j7k0')
ADMIN_LOGIN_PATH = f'/{ADMIN_URL}/'
MIDDLEWARE = [
# ...
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
# ...
## ================================================ ###
# --- ONEHUX SSO MIDDLEWARES (in this order) ---
# 1. First, check if anonymous user can be auto-logged in
'onehux_sso_client.middleware.SilentSSOMiddleware',
# 2. Second, if they ARE logged in, ensure token is fresh
'onehux_sso_client.middleware.SSOTokenRefreshMiddleware',
# 3. Thirdly(Optional),
# 'onehux_sso_client.middleware.SSORateLimitMiddleware', # Optional
]
6. Add url pattern to your project main urls.py
from django.urls import path, include
urlpatterns = [
....
# # =========================================================================
# # SSO ENDPOINTS / URLS
# # =========================================================================
path('sso/', include('onehux_sso_client.urls', namespace='sso')),
....
]
7 Protecting views in SP's
from onehux_sso_client.decorators import (
sso_login_required, # Basic SSO auth
require_sso_role, # Specific role
require_any_role, # Multiple roles
require_admin, # Admin or owner
)
3. Protect your views
# views.py
# Basic SSO protection
@sso_login_required
def dashboard(request):
pass
# Only owners can access
@require_sso_role('owner')
def owner_panel(request):
pass
# Owners OR admins can access
@require_any_role('owner', 'admin')
def management(request):
pass
Advanced Usage
Manual OAuth2 Flow
from onehux_sso_client import OnehuxClient
# Initialize client
client = OnehuxClient(
client_id='your-client-id',
client_secret='your-client-secret',
redirect_uri='http://yourapp.com/oauth/callback',
onehux_base_url='https://accounts.onehux.com'
)
# 1. Generate authorization URL
auth_url, state, code_verifier = client.get_authorization_url(
scopes=['openid', 'profile', 'email']
)
# Store state and code_verifier in session, then redirect user to auth_url
# 2. Exchange authorization code for tokens (in callback view)
tokens = client.exchange_code_for_tokens(
code='authorization-code',
code_verifier=code_verifier
)
# 3. Get user information
user_info = client.get_user_info(tokens['access_token'])
# 4. Verify ID token (optional)
id_token_payload = client.verify_id_token(tokens['id_token'])
Token Refresh
# Refresh an expired access token
new_tokens = client.refresh_access_token(refresh_token)
Webhook Handling
Onehux sends webhooks for user events (login, logout, profile updates). The client automatically handles these via the onehux_webhook view.
Webhook Events:
user.login- User logged into your applicationuser.logout- User logged out (global SLO)user.updated- User profile was updated
Webhook Payload Example:
{
"event": "user.updated",
"timestamp": "2024-01-15T12:00:00Z",
"user": {
"sub": "user-uuid",
"email": "user@example.com",
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"profile_version": 5
}
}
Configuration Options
| Setting | Required | Description |
|---|---|---|
ONEHUX_CLIENT_ID |
Yes | Your application's client ID from Onehux |
ONEHUX_CLIENT_SECRET |
Yes | Your application's client secret |
ONEHUX_REDIRECT_URI |
Yes | OAuth2 callback URL |
ONEHUX_BASE_URL |
No | Onehux platform URL (default: https://accounts.onehux.com) |
ONEHUX_WEBHOOK_SECRET |
No | Secret for webhook signature verification |
ONEHUX_LOGIN_URL |
No | Custom login URL (default: /oauth/login/) |
Security Features
- PKCE (Proof Key for Code Exchange) - Protects against authorization code interception
- State Parameter - CSRF protection for OAuth2 flow
- Webhook Signature Verification - HMAC-SHA256 validation
- Token Validation - JWT signature verification with RSA keys
- Secure Token Storage - Session-based token management
Development
# Clone the repository
git clone https://github.com/programmerisaac/onehux-sso-client.git
cd onehux-sso-client
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black onehux_sso_client/
# Lint code
flake8 onehux_sso_client/
Example Application
See the example-service-provider directory for a complete Django application demonstrating SSO/SLO integration.
Support
- Documentation: https://docs.onehux.com
- Issues: https://github.com/programmerisaac/onehux-sso-client/issues
- Email: support@onehux.com
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please read our Contributing Guidelines first.
Changelog
1.0.0 (2025-12-18)
- Bug fixes
- Improved token validation
- Better error handling
- Single Logout bug fix
- Properly synchronize user data accross service providers
0.1.0 (2025-12-15)
- Initial release
- OAuth2/OIDC authentication with PKCE
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file onehux_sso_client-1.1.0.tar.gz.
File metadata
- Download URL: onehux_sso_client-1.1.0.tar.gz
- Upload date:
- Size: 48.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fce2c8e6cc0baaef237bd9cfc3527c7937895ba45b7bc9980af7f627ebb8a3c
|
|
| MD5 |
a8a1b27874ce1847fc058e729e87482f
|
|
| BLAKE2b-256 |
93c49b7d872b37105517617d97e608909a17a8ecde745f47102cf17cfaa531bd
|
File details
Details for the file onehux_sso_client-1.1.0-py3-none-any.whl.
File metadata
- Download URL: onehux_sso_client-1.1.0-py3-none-any.whl
- Upload date:
- Size: 57.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
254776f62be77703b4f1f9a679a45cef776e52ca108c44bd76643c5358a0474a
|
|
| MD5 |
aeba07fa5356bcb55c3f0e2a9c82c8d4
|
|
| BLAKE2b-256 |
f0e6f662feeb5ec90e22026cac792555ca652477945fe2b5319fccf11f245b7b
|