A powerful Traefik middleware plugin that integrates Casdoor authentication to protect your HTTP services. This solution provides seamless SSO (Single Sign-On) capabilities without requiring any changes to your backend services.
- Features
- Architecture
- Installation
- Quick Start
- Configuration
- How It Works
- Docker Deployment
- Development
- Contributing
- License
- Zero Backend Changes: Add authentication to any HTTP service without modifying your application code
- Seamless SSO: Integrate with Casdoor for centralized authentication and user management
- Traefik Middleware: Implemented as a native Traefik plugin for easy integration
- Session Management: Automatic session handling with secure cookies
- OAuth 2.0 Flow: Complete OAuth 2.0 implementation with PKCE support
- Request Forwarding: Transparent request modification and forwarding
- Stateless Architecture: Webhook-based design for scalability
This solution consists of two main components:
- Traefik Plugin: A middleware that intercepts HTTP requests and forwards them to the webhook for authentication decisions
- Authentication Webhook: A service that validates user sessions, handles OAuth flows, and instructs the plugin how to process requests
┌─────────┐ ┌──────────────┐ ┌──────────┐ ┌─────────┐
│ Client │─────▶│ Traefik │─────▶│ Webhook │─────▶│ Casdoor │
│ │ │ Plugin │ │ Service │ │ Server │
└─────────┘ └──────────────┘ └──────────┘ └─────────┘
│ │
└─────────────────────┘
Authentication Flow
A pre-built webhook image is available for easy deployment:
docker pull ghcr.io/lostb1t/traefik-casdoor-auth:latestFor more details, visit: https://github.com/lostb1t/traefik-casdoor-auth
Prerequisites:
- Go 1.16 or higher
- Traefik v2.x
- Docker (for running example services)
- A running Casdoor instance
Clone the repository:
git clone https://github.com/casdoor/traefik-casdoor-auth.git
cd traefik-casdoor-auth- Access your Casdoor admin panel
- Create a new application for Traefik authentication
- Note down the following details:
- Client ID
- Client Secret
- Organization Name
- Application Name
For detailed instructions, see Casdoor Application Configuration.
Create or update your traefik.yml:
entryPoints:
web:
address: ":80"
experimental:
localPlugins:
example:
moduleName: github.com/casdoor/plugindemo
api:
insecure: true
providers:
file:
filename: dev.ymlNote: The moduleName must match the path relative to plugins-local/src/ and the module name in plugins-local/src/github.com/casdoor/plugindemo/.traefik.yml.
Create dev.yml:
http:
routers:
my-router:
rule: host(`webhook.domain.local`)
service: service-foo
entryPoints:
- web
middlewares:
- my-plugin
services:
service-foo:
loadBalancer:
servers:
- url: http://127.0.0.1:5000
middlewares:
my-plugin:
plugin:
example:
multationWebhook: "http://webhook.domain.local:9999/auth"Create or update conf/plugin.json:
{
"casdoorEndpoint": "http://webhook.domain.local:8000",
"casdoorClientId": "YOUR_CLIENT_ID",
"casdoorClientSecret": "YOUR_CLIENT_SECRET",
"casdoorOrganization": "YOUR_ORGANIZATION",
"casdoorApplication": "YOUR_APPLICATION",
"pluginEndPoint": "http://webhook.domain.local:9999"
}Configuration Parameters:
| Parameter | Description |
|---|---|
casdoorEndpoint |
URL of your Casdoor server |
casdoorClientId |
Client ID from Casdoor application |
casdoorClientSecret |
Client secret from Casdoor application |
casdoorOrganization |
Organization name in Casdoor |
casdoorApplication |
Application name in Casdoor |
pluginEndPoint |
URL where the webhook service is accessible |
Add the following entry to your hosts file (/etc/hosts on Linux/Mac, C:\Windows\System32\drivers\etc\hosts on Windows):
127.0.0.1 webhook.domain.local
Start the example service:
docker compose up -dThis starts a "whoami" container on port 5000 - a simple HTTP service that echoes request information.
Start Traefik:
sudo traefik --configFile="traefik.yml" --log.level=DEBUGStart the webhook service:
go run cmd/webhook/main.go -configFile="conf/plugin.json"Visit http://webhook.domain.local in your browser.
- First visit: You'll be redirected to Casdoor for authentication
- After login: You'll be redirected back and see the "whoami" service output
The plugin accepts the following parameter:
multationWebhook: The URL of the authentication webhook endpoint
All webhook configuration is stored in conf/plugin.json. See the Quick Start section for available parameters.
- Initial Request: Client requests a protected resource
- Plugin Intercept: Traefik plugin intercepts the request and forwards it to the webhook
- Session Check: Webhook checks for a valid authentication cookie
- Redirect to Login: If no valid session exists, webhook returns a 302 redirect to Casdoor
- User Authentication: User logs in via Casdoor
- OAuth Callback: Casdoor redirects to the webhook's callback handler
- Token Exchange: Webhook exchanges the authorization code for an access token
- Cookie Creation: Webhook sets a secure authentication cookie
- Original Request Replay: User is redirected to the original URL
- Request Modification: Plugin modifies the request based on webhook instructions and forwards to the backend service
- 2xx Response from Webhook: Request is modified according to webhook instructions and forwarded to the backend
- Non-2xx Response: Request is blocked, and the webhook's response (including status code and body) is returned to the client
For production deployments, you can use Docker Compose. Here's an example configuration:
version: '3'
services:
traefik:
image: traefik:v2.9
command:
- "--configFile=/etc/traefik/traefik.yml"
- "--log.level=INFO"
ports:
- "80:80"
- "443:443"
volumes:
- ./traefik.yml:/etc/traefik/traefik.yml
- ./dev.yml:/etc/traefik/dev.yml
- ./plugins-local:/plugins-local
casdoor-auth:
image: ghcr.io/lostb1t/traefik-casdoor-auth:latest
environment:
- CONFIG_FILE=/config/plugin.json
volumes:
- ./conf:/config
ports:
- "9999:9999"Run the plugin tests:
cd plugins-local/src/github.com/casdoor/plugindemo
go test -v ./....
├── cmd/
│ └── webhook/ # Webhook service main package
├── internal/
│ ├── config/ # Configuration handling
│ ├── handler/ # HTTP handlers
│ └── httpstate/ # Session state management
├── plugins-local/
│ └── src/
│ └── github.com/
│ └── casdoor/
│ └── plugindemo/ # Traefik plugin implementation
├── conf/ # Configuration files
├── .github/
│ └── workflows/ # CI/CD workflows
└── README.md
go build -o webhook cmd/webhook/main.goContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes using Conventional Commits
- Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project uses semantic-release for automated version management and package publishing. Please use the following commit message format:
feat:- A new feature (triggers minor version bump)fix:- A bug fix (triggers patch version bump)docs:- Documentation changesstyle:- Code style changes (formatting, etc.)refactor:- Code refactoringperf:- Performance improvementstest:- Adding or updating testschore:- Maintenance tasks
Example: feat: add support for custom claim mapping
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Traefik - Cloud Native Application Proxy
- Casdoor - UI-first Identity Access Management (IAM) / Single-Sign-On (SSO) platform
Made with ❤️ by the Casdoor team