refactor(auth): single-domain setup, remove cross-domain cookie hackery

This commit is contained in:
Claus Lohmar 2026-06-15 09:27:34 +00:00
parent 9f7e4c8a68
commit 95308c880b
4 changed files with 4 additions and 14 deletions

View file

@ -45,8 +45,8 @@ SMTP_PORT_DEFAULT="587"
SMTP_USER_DEFAULT="post@2-4-h.app" SMTP_USER_DEFAULT="post@2-4-h.app"
IMAP_HOST_DEFAULT="imap.openxchange.eu" IMAP_HOST_DEFAULT="imap.openxchange.eu"
IMAP_PORT_DEFAULT="993" IMAP_PORT_DEFAULT="993"
NEXTWKS_URL_DEFAULT="https://wks.lohmar.co.uk" NEXTWKS_URL_DEFAULT="https://app.nextwks.eu"
AUTH_URL_DEFAULT="https://auth.lohmar.co.uk" AUTH_URL_DEFAULT="https://app.nextwks.eu/auth"
# ============================================================ # ============================================================
# AUTO-CLONE: if running standalone (not from repo), clone first # AUTO-CLONE: if running standalone (not from repo), clone first
@ -239,7 +239,6 @@ oidc:
client_id: "nextwks" client_id: "nextwks"
client_secret: "" client_secret: ""
redirect_url: "${NEXTWKS_URL}/auth/callback" redirect_url: "${NEXTWKS_URL}/auth/callback"
domain: "${NEXTWKS_DOMAIN}"
smtp: smtp:
host: "${SMTP_HOST}" host: "${SMTP_HOST}"
port: ${SMTP_PORT} port: ${SMTP_PORT}

View file

@ -17,7 +17,6 @@ type OIDCConfig struct {
ClientID string ClientID string
ClientSecret string ClientSecret string
RedirectURL string RedirectURL string
Domain string
} }
// OIDCHandler handles OIDC authentication flows with Authelia. // OIDCHandler handles OIDC authentication flows with Authelia.
@ -48,7 +47,6 @@ func (h *OIDCHandler) LoginRedirect(w http.ResponseWriter, r *http.Request) {
Name: "oidc_state", Name: "oidc_state",
Value: state, Value: state,
Path: "/", Path: "/",
Domain: h.config.Domain,
MaxAge: 300, MaxAge: 300,
HttpOnly: true, HttpOnly: true,
SameSite: http.SameSiteLaxMode, SameSite: http.SameSiteLaxMode,
@ -57,7 +55,6 @@ func (h *OIDCHandler) LoginRedirect(w http.ResponseWriter, r *http.Request) {
Name: "oidc_verifier", Name: "oidc_verifier",
Value: verifier, Value: verifier,
Path: "/", Path: "/",
Domain: h.config.Domain,
MaxAge: 300, MaxAge: 300,
HttpOnly: true, HttpOnly: true,
SameSite: http.SameSiteLaxMode, SameSite: http.SameSiteLaxMode,
@ -134,7 +131,6 @@ func (h *OIDCHandler) Callback(w http.ResponseWriter, r *http.Request) {
Name: "nextwks_session", Name: "nextwks_session",
Value: token, Value: token,
Path: "/", Path: "/",
Domain: h.config.Domain,
MaxAge: 3600, MaxAge: 3600,
HttpOnly: true, HttpOnly: true,
SameSite: http.SameSiteLaxMode, SameSite: http.SameSiteLaxMode,
@ -230,7 +226,6 @@ func (h *OIDCHandler) AuthGateMiddleware(next http.Handler) http.Handler {
if !ok { if !ok {
// Check if force-login is requested (after logout) // Check if force-login is requested (after logout)
if _, ferr := r.Cookie("force_login"); ferr == nil { if _, ferr := r.Cookie("force_login"); ferr == nil {
http.SetCookie(w, &http.Cookie{Name: "force_login", Value: "", Path: "/", Domain: h.config.Domain, MaxAge: -1, HttpOnly: true})
h.LoginRedirectWithPrompt(w, r, "login") h.LoginRedirectWithPrompt(w, r, "login")
return return
} }
@ -248,8 +243,6 @@ func (h *OIDCHandler) LoginRedirectWithPrompt(w http.ResponseWriter, r *http.Req
verifier := generateToken(32) verifier := generateToken(32)
challenge := pkceChallenge(verifier) challenge := pkceChallenge(verifier)
http.SetCookie(w, &http.Cookie{Name: "oidc_state", Value: state, Path: "/", Domain: h.config.Domain, MaxAge: 300, HttpOnly: true, SameSite: http.SameSiteLaxMode})
http.SetCookie(w, &http.Cookie{Name: "oidc_verifier", Value: verifier, Path: "/", Domain: h.config.Domain, MaxAge: 300, HttpOnly: true, SameSite: http.SameSiteLaxMode})
authURL := fmt.Sprintf( authURL := fmt.Sprintf(
"%s/api/oidc/authorize?prompt=%s&response_type=code&client_id=%s&redirect_uri=%s&scope=openid+profile+email&state=%s&nonce=%s&code_challenge=%s&code_challenge_method=S256", "%s/api/oidc/authorize?prompt=%s&response_type=code&client_id=%s&redirect_uri=%s&scope=openid+profile+email&state=%s&nonce=%s&code_challenge=%s&code_challenge_method=S256",

View file

@ -47,11 +47,10 @@ type AutheliaConfig struct {
// OIDCConfig holds the OIDC provider settings (Authelia). // OIDCConfig holds the OIDC provider settings (Authelia).
type OIDCConfig struct { type OIDCConfig struct {
IssuerURL string `yaml:"issuer_url"` // Public-facing URL users reach (e.g., https://auth.sechpoint.app) IssuerURL string `yaml:"issuer_url"` // Public-facing Authelia URL (e.g., https://app.nextwks.eu/auth)
ClientID string `yaml:"client_id"` ClientID string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"` ClientSecret string `yaml:"client_secret"`
RedirectURL string `yaml:"redirect_url"` RedirectURL string `yaml:"redirect_url"`
Domain string `yaml:"domain"`
} }
type SMTPConfig struct { type SMTPConfig struct {

View file

@ -93,7 +93,6 @@ func main() {
ClientID: cfg.OIDC.ClientID, ClientID: cfg.OIDC.ClientID,
ClientSecret: cfg.OIDC.ClientSecret, ClientSecret: cfg.OIDC.ClientSecret,
RedirectURL: cfg.OIDC.RedirectURL, RedirectURL: cfg.OIDC.RedirectURL,
Domain: cfg.OIDC.Domain,
} }
oidcHandler := auth.NewOIDCHandler(oidcCfg, sessionStore) oidcHandler := auth.NewOIDCHandler(oidcCfg, sessionStore)
@ -132,7 +131,7 @@ func main() {
} }
// First visit: clear cookie and redirect to Authelia logout // First visit: clear cookie and redirect to Authelia logout
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: "nextwks_session", Value: "", Path: "/", Domain: cfg.OIDC.Domain, Name: "nextwks_session", Value: "", Path: "/",
MaxAge: -1, HttpOnly: true, SameSite: http.SameSiteLaxMode, MaxAge: -1, HttpOnly: true, SameSite: http.SameSiteLaxMode,
}) })
logoutURL := fmt.Sprintf("%s/logout?rd=%s/auth/logout", cfg.OIDC.IssuerURL, cfg.OIDC.RedirectURL) logoutURL := fmt.Sprintf("%s/logout?rd=%s/auth/logout", cfg.OIDC.IssuerURL, cfg.OIDC.RedirectURL)