1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-05-23 22:40:31 +02:00

Make HTTPS Redirect middleware Reverse Proxy aware

This commit is contained in:
Nick Meves 2021-01-02 13:16:45 -08:00
parent 6fb3274ca3
commit f054682fb7
No known key found for this signature in database
GPG Key ID: 93BA8A3CEDCDD1CF
2 changed files with 38 additions and 6 deletions

View File

@ -7,7 +7,7 @@ import (
"strings" "strings"
"github.com/justinas/alice" "github.com/justinas/alice"
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/util" requestutil "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests/util"
) )
const httpsScheme = "https" const httpsScheme = "https"
@ -26,10 +26,11 @@ func NewRedirectToHTTPS(httpsPort string) alice.Constructor {
// to the port from the httpsAddress given. // to the port from the httpsAddress given.
func redirectToHTTPS(httpsPort string, next http.Handler) http.Handler { func redirectToHTTPS(httpsPort string, next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
proto := req.Header.Get("X-Forwarded-Proto") proto := requestutil.GetRequestProto(req)
if strings.EqualFold(proto, httpsScheme) || (req.TLS != nil && proto == "") { if strings.EqualFold(proto, httpsScheme) || (req.TLS != nil && proto == req.URL.Scheme) {
// Only care about the connection to us being HTTPS if the proto is empty, // Only care about the connection to us being HTTPS if the proto wasn't
// otherwise the proto is source of truth // from a trusted `X-Forwarded-Proto` (proto == req.URL.Scheme).
// Otherwise the proto is source of truth
next.ServeHTTP(rw, req) next.ServeHTTP(rw, req)
return return
} }
@ -41,7 +42,7 @@ func redirectToHTTPS(httpsPort string, next http.Handler) http.Handler {
// Set the Host in case the targetURL still does not have one // Set the Host in case the targetURL still does not have one
// or it isn't X-Forwarded-Host aware // or it isn't X-Forwarded-Host aware
targetURL.Host = util.GetRequestHost(req) targetURL.Host = requestutil.GetRequestHost(req)
// Overwrite the port if the original request was to a non-standard port // Overwrite the port if the original request was to a non-standard port
if targetURL.Port() != "" { if targetURL.Port() != "" {

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"net/http/httptest" "net/http/httptest"
middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@ -21,6 +22,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
requestString string requestString string
useTLS bool useTLS bool
headers map[string]string headers map[string]string
reverseProxy bool
expectedStatus int expectedStatus int
expectedBody string expectedBody string
expectedLocation string expectedLocation string
@ -35,6 +37,10 @@ var _ = Describe("RedirectToHTTPS suite", func() {
if in.useTLS { if in.useTLS {
req.TLS = &tls.ConnectionState{} req.TLS = &tls.ConnectionState{}
} }
scope := &middlewareapi.RequestScope{
ReverseProxy: in.reverseProxy,
}
req = middlewareapi.AddRequestScope(req, scope)
rw := httptest.NewRecorder() rw := httptest.NewRecorder()
@ -52,6 +58,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
requestString: "http://example.com", requestString: "http://example.com",
useTLS: false, useTLS: false,
headers: map[string]string{}, headers: map[string]string{},
reverseProxy: false,
expectedStatus: 308, expectedStatus: 308,
expectedBody: permanentRedirectBody("https://example.com"), expectedBody: permanentRedirectBody("https://example.com"),
expectedLocation: "https://example.com", expectedLocation: "https://example.com",
@ -60,6 +67,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
requestString: "https://example.com", requestString: "https://example.com",
useTLS: true, useTLS: true,
headers: map[string]string{}, headers: map[string]string{},
reverseProxy: false,
expectedStatus: 200, expectedStatus: 200,
expectedBody: "test", expectedBody: "test",
}), }),
@ -69,15 +77,28 @@ var _ = Describe("RedirectToHTTPS suite", func() {
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "HTTPS", "X-Forwarded-Proto": "HTTPS",
}, },
reverseProxy: true,
expectedStatus: 200, expectedStatus: 200,
expectedBody: "test", expectedBody: "test",
}), }),
Entry("without TLS and X-Forwarded-Proto=HTTPS but ReverseProxy not set", &requestTableInput{
requestString: "http://example.com",
useTLS: false,
headers: map[string]string{
"X-Forwarded-Proto": "HTTPS",
},
reverseProxy: false,
expectedStatus: 308,
expectedBody: permanentRedirectBody("https://example.com"),
expectedLocation: "https://example.com",
}),
Entry("with TLS and X-Forwarded-Proto=HTTPS", &requestTableInput{ Entry("with TLS and X-Forwarded-Proto=HTTPS", &requestTableInput{
requestString: "https://example.com", requestString: "https://example.com",
useTLS: true, useTLS: true,
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "HTTPS", "X-Forwarded-Proto": "HTTPS",
}, },
reverseProxy: true,
expectedStatus: 200, expectedStatus: 200,
expectedBody: "test", expectedBody: "test",
}), }),
@ -87,6 +108,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "https", "X-Forwarded-Proto": "https",
}, },
reverseProxy: true,
expectedStatus: 200, expectedStatus: 200,
expectedBody: "test", expectedBody: "test",
}), }),
@ -96,6 +118,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "https", "X-Forwarded-Proto": "https",
}, },
reverseProxy: true,
expectedStatus: 200, expectedStatus: 200,
expectedBody: "test", expectedBody: "test",
}), }),
@ -105,6 +128,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "HTTP", "X-Forwarded-Proto": "HTTP",
}, },
reverseProxy: true,
expectedStatus: 308, expectedStatus: 308,
expectedBody: permanentRedirectBody("https://example.com"), expectedBody: permanentRedirectBody("https://example.com"),
expectedLocation: "https://example.com", expectedLocation: "https://example.com",
@ -115,6 +139,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "HTTP", "X-Forwarded-Proto": "HTTP",
}, },
reverseProxy: true,
expectedStatus: 308, expectedStatus: 308,
expectedBody: permanentRedirectBody("https://example.com"), expectedBody: permanentRedirectBody("https://example.com"),
expectedLocation: "https://example.com", expectedLocation: "https://example.com",
@ -125,6 +150,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "http", "X-Forwarded-Proto": "http",
}, },
reverseProxy: true,
expectedStatus: 308, expectedStatus: 308,
expectedBody: permanentRedirectBody("https://example.com"), expectedBody: permanentRedirectBody("https://example.com"),
expectedLocation: "https://example.com", expectedLocation: "https://example.com",
@ -135,6 +161,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
headers: map[string]string{ headers: map[string]string{
"X-Forwarded-Proto": "http", "X-Forwarded-Proto": "http",
}, },
reverseProxy: true,
expectedStatus: 308, expectedStatus: 308,
expectedBody: permanentRedirectBody("https://example.com"), expectedBody: permanentRedirectBody("https://example.com"),
expectedLocation: "https://example.com", expectedLocation: "https://example.com",
@ -143,6 +170,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
requestString: "http://example.com:8080", requestString: "http://example.com:8080",
useTLS: false, useTLS: false,
headers: map[string]string{}, headers: map[string]string{},
reverseProxy: false,
expectedStatus: 308, expectedStatus: 308,
expectedBody: permanentRedirectBody("https://example.com:8443"), expectedBody: permanentRedirectBody("https://example.com:8443"),
expectedLocation: "https://example.com:8443", expectedLocation: "https://example.com:8443",
@ -151,6 +179,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
requestString: "https://example.com:8443", requestString: "https://example.com:8443",
useTLS: true, useTLS: true,
headers: map[string]string{}, headers: map[string]string{},
reverseProxy: false,
expectedStatus: 200, expectedStatus: 200,
expectedBody: "test", expectedBody: "test",
}), }),
@ -161,6 +190,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
requestString: "/", requestString: "/",
useTLS: false, useTLS: false,
expectedStatus: 308, expectedStatus: 308,
reverseProxy: false,
expectedBody: permanentRedirectBody("https://example.com/"), expectedBody: permanentRedirectBody("https://example.com/"),
expectedLocation: "https://example.com/", expectedLocation: "https://example.com/",
}), }),
@ -171,6 +201,7 @@ var _ = Describe("RedirectToHTTPS suite", func() {
"X-Forwarded-Proto": "HTTP", "X-Forwarded-Proto": "HTTP",
"X-Forwarded-Host": "external.example.com", "X-Forwarded-Host": "external.example.com",
}, },
reverseProxy: true,
expectedStatus: 308, expectedStatus: 308,
expectedBody: permanentRedirectBody("https://external.example.com"), expectedBody: permanentRedirectBody("https://external.example.com"),
expectedLocation: "https://external.example.com", expectedLocation: "https://external.example.com",