Add OIDC provider functionality with validation setup

This commit adds OpenID Connect (OIDC) provider functionality to tinyauth,
allowing it to act as an OIDC identity provider for other applications.

Features:
- OIDC discovery endpoint at /.well-known/openid-configuration
- Authorization endpoint for OAuth 2.0 authorization code flow
- Token endpoint for exchanging authorization codes for tokens
- ID token generation with JWT signing
- JWKS endpoint for public key distribution
- Support for PKCE (code challenge/verifier)
- Nonce validation for ID tokens
- Configurable OIDC clients with redirect URIs, scopes, and grant types

Validation:
- Docker Compose setup for local testing
- OIDC test client (oidc-whoami) with session management
- Nginx reverse proxy configuration
- DNS server (dnsmasq) for custom domain resolution
- Chrome launch script for easy testing

Configuration:
- OIDC configuration in config.yaml
- Example configuration in config.example.yaml
- Database migrations for OIDC client storage
This commit is contained in:
Olivier Dumont
2025-12-30 12:17:40 +01:00
parent 986ac88e14
commit 020fcb9878
21 changed files with 1873 additions and 8 deletions

View File

@@ -2,6 +2,7 @@ package utils
import (
"errors"
"fmt"
"net"
"net/url"
"strings"
@@ -22,13 +23,13 @@ func GetCookieDomain(u string) (string, error) {
host := parsed.Hostname()
if netIP := net.ParseIP(host); netIP != nil {
return "", errors.New("IP addresses not allowed")
return "", fmt.Errorf("IP addresses not allowed for app url '%s' (got IP: %s)", u, host)
}
parts := strings.Split(host, ".")
if len(parts) < 3 {
return "", errors.New("invalid app url, must be at least second level domain")
return "", fmt.Errorf("invalid app url '%s', must be at least second level domain (got %d parts, need 3+)", u, len(parts))
}
domain := strings.Join(parts[1:], ".")
@@ -36,7 +37,7 @@ func GetCookieDomain(u string) (string, error) {
_, err = publicsuffix.DomainFromListWithOptions(publicsuffix.DefaultList, domain, nil)
if err != nil {
return "", errors.New("domain in public suffix list, cannot set cookies")
return "", fmt.Errorf("domain '%s' (from app url '%s') is in public suffix list, cannot set cookies", domain, u)
}
return domain, nil