Skip to content

Commit

Permalink
Track the ReverseProxy option in the request Scope
Browse files Browse the repository at this point in the history
This allows for proper handling of reverse proxy based headers throughout
the lifecycle of a request.
Nick Meves committed Jan 16, 2021
1 parent 8e02fac commit b625de9
Showing 4 changed files with 29 additions and 17 deletions.
2 changes: 1 addition & 1 deletion oauthproxy.go
Original file line number Diff line number Diff line change
@@ -231,7 +231,7 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr
// the OAuth2 Proxy authentication logic kicks in.
// For example forcing HTTPS or health checks.
func buildPreAuthChain(opts *options.Options) (alice.Chain, error) {
chain := alice.New(middleware.NewScope())
chain := alice.New(middleware.NewScope(opts))

if opts.ForceHTTPS {
_, httpsPort, err := net.SplitHostPort(opts.HTTPSAddress)
4 changes: 4 additions & 0 deletions pkg/apis/middleware/scope.go
Original file line number Diff line number Diff line change
@@ -8,6 +8,10 @@ import (
// The RequestScope is used to pass information between different middlewares
// within the chain.
type RequestScope struct {
// ReverseProxy tracks whether OAuth2-Proxy is operating in reverse proxy
// mode and if request `X-Forwarded-*` headers should be trusted
ReverseProxy bool

// Session details the authenticated users information (if it exists).
Session *sessions.SessionState

26 changes: 13 additions & 13 deletions pkg/middleware/scope.go
Original file line number Diff line number Diff line change
@@ -6,26 +6,26 @@ import (

"github.com/justinas/alice"
middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
)

type scopeKey string

// requestScopeKey uses a typed string to reduce likelihood of clasing
// requestScopeKey uses a typed string to reduce likelihood of clashing
// with other context keys
const requestScopeKey scopeKey = "request-scope"

func NewScope() alice.Constructor {
return addScope
}

// addScope injects a new request scope into the request context.
func addScope(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
scope := &middlewareapi.RequestScope{}
contextWithScope := context.WithValue(req.Context(), requestScopeKey, scope)
requestWithScope := req.WithContext(contextWithScope)
next.ServeHTTP(rw, requestWithScope)
})
func NewScope(opts *options.Options) alice.Constructor {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
scope := &middlewareapi.RequestScope{
ReverseProxy: opts.ReverseProxy,
}
contextWithScope := context.WithValue(req.Context(), requestScopeKey, scope)
requestWithScope := req.WithContext(contextWithScope)
next.ServeHTTP(rw, requestWithScope)
})
}
}

// GetRequestScope returns the current request scope from the given request
14 changes: 11 additions & 3 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@ import (
"fmt"
"io/ioutil"
"net/http"

"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/middleware"
)

func GetCertPool(paths []string) (*x509.CertPool, error) {
@@ -28,16 +30,17 @@ func GetCertPool(paths []string) (*x509.CertPool, error) {
// GetRequestProto return the request host header or X-Forwarded-Proto if present
func GetRequestProto(req *http.Request) string {
proto := req.Header.Get("X-Forwarded-Proto")
if proto == "" {
if !isProxied(req) || proto == "" {
proto = req.URL.Scheme
}
return proto
}

// GetRequestHost return the request host header or X-Forwarded-Host if present
// and reverse proxy mode is enabled.
func GetRequestHost(req *http.Request) string {
host := req.Header.Get("X-Forwarded-Host")
if host == "" {
if !isProxied(req) || host == "" {
host = req.Host
}
return host
@@ -46,9 +49,14 @@ func GetRequestHost(req *http.Request) string {
// GetRequestURI return the request host header or X-Forwarded-Uri if present
func GetRequestURI(req *http.Request) string {
uri := req.Header.Get("X-Forwarded-Uri")
if uri == "" {
if !isProxied(req) || uri == "" {
// Use RequestURI to preserve ?query
uri = req.URL.RequestURI()
}
return uri
}

func isProxied(req *http.Request) bool {
scope := middleware.GetRequestScope(req)
return scope.ReverseProxy
}

0 comments on commit b625de9

Please sign in to comment.