A standalone forward authentication service that integrates Casdoor authentication for protecting HTTP services behind reverse proxies like Traefik, Nginx, or Caddy. This service provides seamless SSO (Single Sign-On) capabilities without requiring changes to your backend services.
- Features
- Architecture
- Installation
- Quick Start
- Configuration
- API Endpoints
- Deployment
- Development
- Testing
- 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
- Reverse Proxy Compatible: Works with Traefik, Nginx, Caddy, and other reverse proxies that support forward auth
- Session Management: Automatic session handling with secure cookies
- OAuth 2.0 Flow: Complete OAuth 2.0 implementation
- Stateless Architecture: In-memory state storage for scalability
- Kubernetes Ready: Easy deployment in containerized environments
This service acts as a forward authentication handler that sits between your reverse proxy and backend services:
┌─────────┐ ┌──────────────┐ ┌───────────────┐ ┌─────────┐
│ Client │─────▶│ Reverse Proxy│─────▶│ Forward Auth │─────▶│ Casdoor │
│ │ │ (Traefik/ │ │ Service │ │ Server │
│ │ │ Nginx) │ └───────────────┘ └─────────┘
└─────────┘ └──────────────┘ │
│ │
└─────────────────────┘
Authentication Flow
- Initial Request: Client requests a protected resource
- Forward Auth Check: Reverse proxy forwards request to this service
- Session Validation: Service checks for valid authentication cookies
- Redirect to Login: If no valid session, service returns redirect to Casdoor
- OAuth Flow: User authenticates with Casdoor
- Callback Handling: Service handles OAuth callback and sets session cookies
- Access Granted: Subsequent requests pass authentication and proceed to backend
- Go 1.23.0 or higher
- A running Casdoor instance
- A reverse proxy (Traefik, Nginx, Caddy, etc.)
git clone https://github.com/casdoor/casdoor-forward-auth.git
cd casdoor-forward-auth
go build -o casdoor-forward-auth ./cmd/main.gogo install github.com/casdoor/casdoor-forward-auth/cmd@latest- Access your Casdoor admin panel
- Create a new application for forward authentication
- Configure the redirect URL:
http://your-auth-service:9999/callback - Note down the following details:
- Client ID
- Client Secret
- Organization Name
- Application Name
For detailed instructions, see Casdoor Application Configuration.
Create a configuration file conf/config.json:
{
"casdoorEndpoint": "http://localhost:8000",
"casdoorClientId": "YOUR_CLIENT_ID",
"casdoorClientSecret": "YOUR_CLIENT_SECRET",
"casdoorOrganization": "YOUR_ORGANIZATION",
"casdoorApplication": "YOUR_APPLICATION",
"pluginEndpoint": "http://localhost:9999"
}Configuration Parameters:
| Parameter | Required | Description |
|---|---|---|
casdoorEndpoint |
Yes | URL of your Casdoor server |
casdoorClientId |
Yes | Client ID from Casdoor application |
casdoorClientSecret |
Yes | Client secret from Casdoor application |
casdoorOrganization |
Yes | Organization name in Casdoor |
casdoorApplication |
Yes | Application name in Casdoor |
pluginEndpoint |
Yes | URL where this service is accessible |
./casdoor-forward-auth -configFile=conf/config.jsonThe service will start on port 9999 by default.
http:
routers:
my-router:
rule: "Host(`app.example.com`)"
service: my-service
middlewares:
- forward-auth
middlewares:
forward-auth:
forwardAuth:
address: "http://localhost:9999/auth"
trustForwardHeader: true
services:
my-service:
loadBalancer:
servers:
- url: "http://localhost:8080"location / {
auth_request /auth;
proxy_pass http://backend:8080;
}
location = /auth {
internal;
proxy_pass http://localhost:9999/auth;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-URI $request_uri;
}You can also use environment variables to override configuration:
CASDOOR_ENDPOINT: Casdoor server URLCASDOOR_CLIENT_ID: Application client IDCASDOOR_CLIENT_SECRET: Application client secretCASDOOR_ORGANIZATION: Organization nameCASDOOR_APPLICATION: Application namePLUGIN_ENDPOINT: Forward auth service URL
casdoor-forward-auth [options]
Options:
-configFile string
path to the config file (default "conf/config.json")Forward authentication endpoint. Your reverse proxy should forward authentication requests here.
Response:
200 OK: Authentication successful (with replacement headers/body)307 Temporary Redirect: Redirect to Casdoor login
OAuth callback endpoint. Casdoor redirects here after successful authentication.
Query Parameters:
code: OAuth authorization codestate: State parameter for CSRF protection
Test endpoint for development and debugging.
Create a Dockerfile:
FROM golang:1.23.0-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o casdoor-forward-auth ./cmd/main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/casdoor-forward-auth .
COPY --from=builder /app/conf ./conf
EXPOSE 9999
CMD ["./casdoor-forward-auth"]Build and run:
docker build -t casdoor-forward-auth .
docker run -p 9999:9999 -v $(pwd)/conf:/root/conf casdoor-forward-authExample deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: casdoor-forward-auth
spec:
replicas: 2
selector:
matchLabels:
app: casdoor-forward-auth
template:
metadata:
labels:
app: casdoor-forward-auth
spec:
containers:
- name: casdoor-forward-auth
image: casdoor-forward-auth:latest
ports:
- containerPort: 9999
volumeMounts:
- name: config
mountPath: /root/conf
volumes:
- name: config
configMap:
name: casdoor-config
---
apiVersion: v1
kind: Service
metadata:
name: casdoor-forward-auth
spec:
selector:
app: casdoor-forward-auth
ports:
- port: 9999
targetPort: 9999# Clone the repository
git clone https://github.com/casdoor/casdoor-forward-auth.git
cd casdoor-forward-auth
# Install dependencies
go mod download
# Build
go build -o bin/casdoor-forward-auth ./cmd/main.go
# Run
./bin/casdoor-forward-auth -configFile=conf/config.jsoncasdoor-forward-auth/
├── cmd/
│ └── main.go # Application entry point
├── internal/
│ ├── config/ # Configuration management
│ │ ├── config.go
│ │ └── token.pem # Default certificate
│ ├── handler/ # HTTP request handlers
│ │ ├── casdoor_handler.go
│ │ ├── init.go
│ │ └── util_handler.go
│ └── httpstate/ # Session state management
│ ├── state.go
│ └── state_memory_storage.go
├── conf/
│ └── config.json # Configuration file
├── .github/
│ └── workflows/
│ └── ci.yml # CI/CD pipeline
├── go.mod
├── go.sum
├── LICENSE
└── README.md
go test -v ./...go test -v -cover ./...go test -v ./internal/httpstate/
go test -v ./internal/config/
go test -v ./internal/handler/We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes using Conventional Commits
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
We use semantic-release for automated versioning and releases. Please follow the Conventional Commits specification:
feat:- New features (triggers minor version bump)fix:- Bug fixes (triggers patch version bump)docs:- Documentation changeschore:- Maintenance taskstest:- Test additions or modificationsrefactor:- Code refactoring
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Copyright 2026 The Casdoor Authors.
- Casdoor - Open-source Identity and Access Management (IAM) / Single-Sign-On (SSO) platform
- Casdoor Go SDK - Official Go SDK for Casdoor
- Traefik Casdoor Auth Plugin - Traefik middleware plugin for Casdoor authentication
- Discord - Join our Discord community
- GitHub Discussions - Ask questions and share ideas
- GitHub Issues - Report bugs and request features