@@ -392,76 +392,137 @@ func (h *Handlers) Logout(w http.ResponseWriter, r *http.Request) {
392392 h .writeJSON (w , map [string ]string {"status" : "success" })
393393}
394394
395- // AuthCheck implements auth backend for both nginx auth_request and Traefik ForwardAuth
396- func (h * Handlers ) AuthCheck (w http.ResponseWriter , r * http.Request ) {
397- // Debug logging
398- logrus .Debugf ("AuthCheck request from %s" , r .RemoteAddr )
399- logrus .Debugf ("AuthCheck headers: %+v" , r .Header )
400- logrus .Debugf ("AuthCheck cookies: %+v" , r .Cookies ())
401- logrus .Debugf ("AuthCheck query params: %+v" , r .URL .Query ())
395+ // AuthCheckNginx implements nginx auth_request protocol
396+ func (h * Handlers ) AuthCheckNginx (w http.ResponseWriter , r * http.Request ) {
397+ logrus .Debugf ("Nginx AuthCheck request from %s" , r .RemoteAddr )
398+ logrus .Debugf ("Nginx AuthCheck headers: %+v" , r .Header )
399+ logrus .Debugf ("Nginx AuthCheck cookies: %+v" , r .Cookies ())
402400
403401 session , err := h .store .Get (r , "auth-session" )
404402 if err != nil {
405403 logrus .Errorf ("Failed to get auth session: %v" , err )
406- h . handleUnauthenticated ( w , r )
404+ w . WriteHeader ( http . StatusUnauthorized )
407405 return
408406 }
409407
410408 authenticated , ok := session .Values ["authenticated" ].(bool )
411409 logrus .Debugf ("Session authenticated: %v, ok: %v" , authenticated , ok )
412- logrus .Debugf ("Session values: %+v" , session .Values )
413410
414411 if ! ok || ! authenticated {
415- logrus .Debugf ("User not authenticated" )
416- h . handleUnauthenticated ( w , r )
412+ logrus .Debugf ("User not authenticated, returning 401 for Nginx " )
413+ w . WriteHeader ( http . StatusUnauthorized )
417414 return
418415 }
419416
420- // Optional: Add user info to response headers
417+ // Add user info to response headers for nginx
421418 if userID , ok := session .Values ["user_id" ].(int ); ok {
422419 w .Header ().Set ("X-Auth-User-ID" , strconv .Itoa (userID ))
423420 }
424421 if userEmail , ok := session .Values ["user_email" ].(string ); ok {
425422 w .Header ().Set ("X-Auth-User" , userEmail )
426423 }
427424
428- logrus .Debugf ("User authenticated, returning 200" )
425+ logrus .Debugf ("User authenticated, returning 200 for Nginx " )
429426 w .WriteHeader (http .StatusOK )
430427}
431428
432- // handleUnauthenticated handles unauthenticated requests for both Nginx and Traefik
433- func (h * Handlers ) handleUnauthenticated (w http.ResponseWriter , r * http.Request ) {
434- // Check for redirect parameter (Traefik ForwardAuth typically includes this)
435- redirectURL := r .URL .Query ().Get ("rd" )
436- if redirectURL == "" {
437- // Also check for other common redirect parameter names
438- redirectURL = r .URL .Query ().Get ("redirect" )
429+ // AuthCheckTraefik implements Traefik ForwardAuth protocol
430+ func (h * Handlers ) AuthCheckTraefik (w http.ResponseWriter , r * http.Request ) {
431+ logrus .Debugf ("Traefik AuthCheck request from %s" , r .RemoteAddr )
432+ logrus .Debugf ("Traefik AuthCheck headers: %+v" , r .Header )
433+ logrus .Debugf ("Traefik AuthCheck cookies: %+v" , r .Cookies ())
434+
435+ session , err := h .store .Get (r , "auth-session" )
436+ if err != nil {
437+ logrus .Errorf ("Failed to get auth session: %v" , err )
438+ h .handleTraefikUnauthenticated (w , r )
439+ return
440+ }
441+
442+ authenticated , ok := session .Values ["authenticated" ].(bool )
443+ logrus .Debugf ("Session authenticated: %v, ok: %v" , authenticated , ok )
444+
445+ if ! ok || ! authenticated {
446+ logrus .Debugf ("User not authenticated" )
447+ h .handleTraefikUnauthenticated (w , r )
448+ return
439449 }
440450
441- // If redirect parameter is present, return 302 redirect (Traefik ForwardAuth)
451+ // Add user info to response headers for Traefik
452+ if userID , ok := session .Values ["user_id" ].(int ); ok {
453+ w .Header ().Set ("X-Auth-User-ID" , strconv .Itoa (userID ))
454+ }
455+ if userEmail , ok := session .Values ["user_email" ].(string ); ok {
456+ w .Header ().Set ("X-Auth-User" , userEmail )
457+ }
458+
459+ logrus .Debugf ("User authenticated, returning 200 for Traefik" )
460+ w .WriteHeader (http .StatusOK )
461+ }
462+
463+ // handleTraefikUnauthenticated handles unauthenticated requests for Traefik ForwardAuth
464+ func (h * Handlers ) handleTraefikUnauthenticated (w http.ResponseWriter , r * http.Request ) {
465+ // Construct the original URL from Traefik headers
466+ redirectURL := h .constructOriginalURL (r )
467+
468+ logrus .Debugf ("Constructed redirect URL from headers: %s" , redirectURL )
469+
470+ // Construct login URL with redirect parameter
471+ loginURL := "/login.html"
442472 if redirectURL != "" {
443- logrus .Debugf ("Redirect parameter found (%s), returning 302 redirect for Traefik" , redirectURL )
444-
445- // Construct login URL with redirect parameter
446- loginURL := "/login.html?redirect=" + redirectURL
447-
448- // If we have a host header, construct a full URL
449- if host := r .Header .Get ("Host" ); host != "" {
450- scheme := "http"
451- if r .Header .Get ("X-Forwarded-Proto" ) == "https" || r .TLS != nil {
452- scheme = "https"
453- }
454- loginURL = scheme + "://" + host + loginURL
473+ loginURL += "?redirect=" + redirectURL
474+ }
475+
476+ // If we have a host header, construct a full URL
477+ if host := r .Header .Get ("Host" ); host != "" {
478+ scheme := "http"
479+ if r .Header .Get ("X-Forwarded-Proto" ) == "https" || r .TLS != nil {
480+ scheme = "https"
455481 }
482+ loginURL = scheme + "://" + host + loginURL
483+ }
456484
457- w .Header ().Set ("Location" , loginURL )
458- w .WriteHeader (http .StatusFound ) // 302
459- return
485+ logrus .Debugf ("Returning 302 redirect to: %s" , loginURL )
486+ w .Header ().Set ("Location" , loginURL )
487+ w .WriteHeader (http .StatusFound ) // 302
488+ }
489+
490+ // constructOriginalURL reconstructs the original URL from Traefik forwarded headers
491+ func (h * Handlers ) constructOriginalURL (r * http.Request ) string {
492+ // Traefik sets various headers that we can use to reconstruct the original URL
493+
494+ // Check for X-Forwarded-Host (original host)
495+ host := r .Header .Get ("X-Forwarded-Host" )
496+ if host == "" {
497+ host = r .Header .Get ("X-Original-Host" )
498+ }
499+ if host == "" {
500+ // Fallback to Host header
501+ host = r .Header .Get ("Host" )
502+ }
503+
504+ // Check for X-Forwarded-Uri (original path + query)
505+ uri := r .Header .Get ("X-Forwarded-Uri" )
506+ if uri == "" {
507+ uri = r .Header .Get ("X-Original-URI" )
508+ }
509+ if uri == "" {
510+ // Fallback to request URI
511+ uri = r .RequestURI
512+ }
513+
514+ // Determine scheme
515+ scheme := "http"
516+ if r .Header .Get ("X-Forwarded-Proto" ) == "https" || r .TLS != nil {
517+ scheme = "https"
518+ }
519+
520+ if host == "" {
521+ return ""
460522 }
461523
462- // No redirect parameter, return 401 (Nginx auth_request)
463- logrus .Debugf ("No redirect parameter, returning 401 for Nginx auth_request" )
464- w .WriteHeader (http .StatusUnauthorized )
524+ // Construct the full URL
525+ return scheme + "://" + host + uri
465526}
466527
467528// GetAuthStatus returns the current authentication status
0 commit comments