Skip to content

Commit fdcb253

Browse files
committed
refactor: better module handling per proxy
1 parent 13bb3ca commit fdcb253

1 file changed

Lines changed: 61 additions & 48 deletions

File tree

internal/controller/proxy_controller.go

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ import (
1717
"github.com/google/go-querystring/query"
1818
)
1919

20-
type RequestType int
20+
type AuthModuleType int
2121

2222
const (
23-
AuthRequest RequestType = iota
23+
AuthRequest AuthModuleType = iota
2424
ExtAuthz
2525
ForwardAuth
2626
)
@@ -38,7 +38,7 @@ type ProxyContext struct {
3838
Proto string
3939
Path string
4040
Method string
41-
Type RequestType
41+
Type AuthModuleType
4242
IsBrowser bool
4343
}
4444

@@ -341,10 +341,6 @@ func (controller *ProxyController) getForwardAuthContext(c *gin.Context) (ProxyC
341341

342342
method := c.Request.Method
343343

344-
if method != http.MethodGet {
345-
return ProxyContext{}, errors.New("method not allowed")
346-
}
347-
348344
return ProxyContext{
349345
Host: host,
350346
Proto: proto,
@@ -372,10 +368,6 @@ func (controller *ProxyController) getAuthRequestContext(c *gin.Context) (ProxyC
372368
path := url.Path
373369
method := c.Request.Method
374370

375-
if method != http.MethodGet {
376-
return ProxyContext{}, errors.New("method not allowed")
377-
}
378-
379371
return ProxyContext{
380372
Host: host,
381373
Proto: proto,
@@ -398,19 +390,58 @@ func (controller *ProxyController) getExtAuthzContext(c *gin.Context) (ProxyCont
398390
return ProxyContext{}, errors.New("host not found")
399391
}
400392

401-
// Seems like we can't get the path?
393+
// We get the path from the query string
394+
path := c.Query("path")
402395

403396
// For envoy we need to support every method
404397
method := c.Request.Method
405398

406399
return ProxyContext{
407400
Host: host,
408401
Proto: proto,
402+
Path: path,
409403
Method: method,
410404
Type: ExtAuthz,
411405
}, nil
412406
}
413407

408+
func (controller *ProxyController) determineAuthModules(proxy string) []AuthModuleType {
409+
switch proxy {
410+
case "traefik":
411+
return []AuthModuleType{ForwardAuth}
412+
case "envoy":
413+
return []AuthModuleType{ExtAuthz, ForwardAuth}
414+
case "nginx":
415+
return []AuthModuleType{AuthRequest, ForwardAuth}
416+
default:
417+
return []AuthModuleType{ForwardAuth}
418+
}
419+
}
420+
421+
func (controller *ProxyController) getContextFromAuthModule(c *gin.Context, module AuthModuleType) (ProxyContext, error) {
422+
switch module {
423+
case ForwardAuth:
424+
ctx, err := controller.getForwardAuthContext(c)
425+
if err != nil {
426+
return ProxyContext{}, err
427+
}
428+
return ctx, nil
429+
case ExtAuthz:
430+
ctx, err := controller.getExtAuthzContext(c)
431+
if err != nil {
432+
return ProxyContext{}, err
433+
}
434+
return ctx, nil
435+
case AuthRequest:
436+
ctx, err := controller.getAuthRequestContext(c)
437+
if err != nil {
438+
return ProxyContext{}, err
439+
}
440+
return ctx, nil
441+
}
442+
return ProxyContext{}, fmt.Errorf("unsupported auth module: %v", module)
443+
}
444+
414445
func (controller *ProxyController) getProxyContext(c *gin.Context) (ProxyContext, error) {
415446
var req Proxy
416447

@@ -419,54 +450,36 @@ func (controller *ProxyController) getProxyContext(c *gin.Context) (ProxyContext
419450
return ProxyContext{}, err
420451
}
421452

453+
tlog.App.Debug().Msgf("Proxy: %v", req.Proxy)
454+
455+
tlog.App.Trace().Interface("headers", c.Request.Header).Msg("Request headers")
456+
457+
authModules := controller.determineAuthModules(req.Proxy)
458+
422459
var ctx ProxyContext
423460

424-
switch req.Proxy {
425-
// For nginx we need to handle both forward_auth and auth_request extraction since it can be
426-
// used either with something line nginx proxy manager with advanced config or with
427-
// the kubernetes ingress controller
428-
case "nginx":
429-
tlog.App.Debug().Str("proxy", req.Proxy).Msg("Attempting forward_auth compatible extraction")
430-
forwardAuthCtx, err := controller.getForwardAuthContext(c)
461+
for _, module := range authModules {
462+
tlog.App.Debug().Msgf("Trying auth module: %v", module)
463+
ctx, err = controller.getContextFromAuthModule(c, module)
431464
if err == nil {
432-
tlog.App.Debug().Str("proxy", req.Proxy).Msg("Extractions success using forward_auth")
433-
ctx = forwardAuthCtx
434-
} else {
435-
tlog.App.Debug().Str("proxy", req.Proxy).Msg("Extractions failed using forward_auth trying with auth_request")
436-
authRequestCtx, err := controller.getAuthRequestContext(c)
437-
if err != nil {
438-
tlog.App.Warn().Str("proxy", req.Proxy).Msg("Failed to determine required module for header extraction")
439-
return ProxyContext{}, err
440-
}
441-
ctx = authRequestCtx
442-
}
443-
case "envoy":
444-
tlog.App.Debug().Str("proxy", req.Proxy).Msg("Attempting ext_authz compatible extraction")
445-
extAuthzCtx, err := controller.getExtAuthzContext(c)
446-
if err != nil {
447-
tlog.App.Warn().Str("proxy", req.Proxy).Msg("Failed to determine required module for header extraction")
448-
return ProxyContext{}, err
449-
}
450-
ctx = extAuthzCtx
451-
// By default we fallback to the forward_auth module which supports most proxies like traefik or caddy
452-
default:
453-
tlog.App.Debug().Str("proxy", req.Proxy).Msg("Attempting forward_auth compatible extraction")
454-
forwardAuthCtx, err := controller.getForwardAuthContext(c)
455-
if err != nil {
456-
tlog.App.Warn().Str("proxy", req.Proxy).Msg("Failed to determine required module for header extraction")
457-
return ProxyContext{}, err
465+
tlog.App.Debug().Msgf("Auth module %v succeeded", module)
466+
break
458467
}
459-
ctx = forwardAuthCtx
468+
tlog.App.Debug().Err(err).Msgf("Auth module %v failed", module)
469+
}
470+
471+
if err != nil {
472+
return ProxyContext{}, err
460473
}
461474

462475
// We don't care if the header is empty, we will just assume it's not a browser
463476
userAgent, _ := controller.getHeader(c, "user-agent")
464477
isBrowser := BrowserUserAgentRegex.MatchString(userAgent)
465478

466479
if isBrowser {
467-
tlog.App.Debug().Msg("Request identified as (most likely) coming from a browser")
480+
tlog.App.Debug().Msg("Request identified as coming from a browser")
468481
} else {
469-
tlog.App.Debug().Msg("Request identified as (most likely) coming from a non-browser client")
482+
tlog.App.Debug().Msg("Request identified as coming from a non-browser client")
470483
}
471484

472485
ctx.IsBrowser = isBrowser

0 commit comments

Comments
 (0)