traefik-sso
traefik-sso copied to clipboard
a simple SSO PHP Application to authenticate against Docker Services - README follows...
Traefik SSO
A lightweight PHP-based single sign-on authentication service designed to work seamlessly with Traefik ForwardAuth middleware.
Features
- Simplified admin access without requiring username input
- JWT-based authentication with configurable expiration
- Multiple access lists for granular user permissions
- Cookie-based session management for persistent authentication
- Event system for custom authentication hooks
- Global logout functionality to invalidate all sessions
Quick Start
Docker Compose
services:
sso:
image: robinmoser/sso:latest
environment:
HOSTNAME: sso.example.com
WEB_ALIAS_DOMAIN: sso.example.com
volumes:
- ./config:/app/config:ro
labels:
- 'traefik.enable=true'
- 'traefik.http.services.sso.loadbalancer.server.port=80'
- 'traefik.http.routers.sso.rule=Host(`sso.example.com`)'
Configuration
- Copy
configs/credentials.example.phptoconfig/credentials.php - Update user credentials and access lists
Users & Access Lists
$credentials = [
'expire' => '14 day',
'users' => [
'admin' => '$1$password_hash...',
'user2' => '$1$password_hash...',
'user1' => '$1$password_hash...',
],
'lists' => [
// default access list for the admin user:
'private' => ['admin'],
'family' => ['admin', 'user2', 'user3'],
]
];
- Configure your Traefik Serivices to use the SSO service
services:
myservice:
image: my_service_image
labels:
- 'traefik.enable=true'
- 'traefik.http.services.myservice.loadbalancer.server.port=80'
- 'traefik.http.routers.myservice.middlewares=auth'
- 'traefik.http.routers.myservice.rule=Host(`service.example.com`)'
- 'traefik.http.middlewares.auth.forwardauth.address=http://sso.example.com/'
Authentication Modes
Admin Mode (Default)
When no ?list= parameter is provided, only a password is required, as the only allowed user is admin.
This provides simplified access for admin-only services.
- 'traefik.http.middlewares.auth.forwardauth.address=http://sso.example.com/'
With Access Lists
When configuring Traefik ForwardAuth with a ?list= parameter, users must provide both username and password:
- 'traefik.http.middlewares.auth.forwardauth.address=http://sso.example.com/?list=family'
This gives access to all users defined in the specified access list.
Global Logout
To invalidate all active JWT tokens and force all users to re-authenticate, enter logout in the password field on the SSO login page. This immediately expires all existing sessions across all services.
Custom Events
The SSO service includes an event system that triggers on authentication actions.
You can create custom event handlers by placing PHP files in the events/ directory.
Available Events
user.login.success- Triggered after successful authenticationuser.login.failure- Triggered after failed authentication attemptsuser.logout- Triggered when global logout is performed
Event Handler Example
Create a file in events/ directory to handle authentication events:
<?php
// events/pushover.php
Event::bind('user.login.failure', function($args = array()) {
pushover("Login failed! (IP: " . $_SERVER['HTTP_X_REAL_IP'] . ")\n"
. "User: " . $args[0] . "@" . $args[1] . "\n" . $_GET['service']);
});
Event::bind('user.login.success', function($args = array()) {
pushover("Login succeeded! (IP: " . $_SERVER['HTTP_X_REAL_IP'] . ")\n"
. "User: " . $args[0] . "@" . $args[1] . "\n" . $_GET['service']);
});
function pushover($message) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.pushover.net/1/messages.json');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'token' => 'YOUR_APP_TOKEN',
'user' => 'YOUR_USER_KEY',
'message' => $message
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
}
All PHP files in the events/ directory are automatically loaded and executed.
How It Works
- User accesses a protected service behind Traefik
- Traefik forwards auth request to SSO service
- If not authenticated, user is redirected to login page
- After successful login, JWT token is issued and user redirected back
- Subsequent requests use local cookies for authentication
License
Created by Robin Moser, 2020