Feature: Allowing relative redirect url though an option (#2183)
* Adding relative redirect url option * Updating CHANGELOG.md * tests: adding unit test for getOAuthRedirectURI --------- Co-authored-by: Joel Speed <Joel.speed@hotmail.co.uk>
This commit is contained in:
parent
464f3bcf53
commit
601477a52c
|
|
@ -7,10 +7,12 @@
|
||||||
## Breaking Changes
|
## Breaking Changes
|
||||||
|
|
||||||
## Changes since v7.5.1
|
## Changes since v7.5.1
|
||||||
|
|
||||||
- [#2128](https://github.com/oauth2-proxy/oauth2-proxy/pull/2128) Update dependencies (@vllvll)
|
- [#2128](https://github.com/oauth2-proxy/oauth2-proxy/pull/2128) Update dependencies (@vllvll)
|
||||||
- [#2274](https://github.com/oauth2-proxy/oauth2-proxy/pull/2274) Upgrade golang.org/x/net to v0.17.0 (@pierluigilenoci)
|
- [#2274](https://github.com/oauth2-proxy/oauth2-proxy/pull/2274) Upgrade golang.org/x/net to v0.17.0 (@pierluigilenoci)
|
||||||
- [#2282](https://github.com/oauth2-proxy/oauth2-proxy/pull/2282) Fixed checking Google Groups membership using Google Application Credentials (@kvanzuijlen)
|
- [#2282](https://github.com/oauth2-proxy/oauth2-proxy/pull/2282) Fixed checking Google Groups membership using Google Application Credentials (@kvanzuijlen)
|
||||||
|
- [#2183](https://github.com/oauth2-proxy/oauth2-proxy/pull/2183) Allowing relative redirect url though an option
|
||||||
|
-
|
||||||
# V7.5.1
|
# V7.5.1
|
||||||
|
|
||||||
## Release Highlights
|
## Release Highlights
|
||||||
|
|
|
||||||
|
|
@ -165,6 +165,7 @@ An example [oauth2-proxy.cfg](https://github.com/oauth2-proxy/oauth2-proxy/blob/
|
||||||
| `--real-client-ip-header` | string | Header used to determine the real IP of the client, requires `--reverse-proxy` to be set (one of: X-Forwarded-For, X-Real-IP, or X-ProxyUser-IP) | X-Real-IP |
|
| `--real-client-ip-header` | string | Header used to determine the real IP of the client, requires `--reverse-proxy` to be set (one of: X-Forwarded-For, X-Real-IP, or X-ProxyUser-IP) | X-Real-IP |
|
||||||
| `--redeem-url` | string | Token redemption endpoint | |
|
| `--redeem-url` | string | Token redemption endpoint | |
|
||||||
| `--redirect-url` | string | the OAuth Redirect URL, e.g. `"https://internalapp.yourcompany.com/oauth2/callback"` | |
|
| `--redirect-url` | string | the OAuth Redirect URL, e.g. `"https://internalapp.yourcompany.com/oauth2/callback"` | |
|
||||||
|
| `--relative-redirect-url` | bool | allow relative OAuth Redirect URL.` | |
|
||||||
| `--redis-cluster-connection-urls` | string \| list | List of Redis cluster connection URLs (e.g. `redis://HOST[:PORT]`). Used in conjunction with `--redis-use-cluster` | |
|
| `--redis-cluster-connection-urls` | string \| list | List of Redis cluster connection URLs (e.g. `redis://HOST[:PORT]`). Used in conjunction with `--redis-use-cluster` | |
|
||||||
| `--redis-connection-url` | string | URL of redis server for redis session storage (e.g. `redis://HOST[:PORT]`) | |
|
| `--redis-connection-url` | string | URL of redis server for redis session storage (e.g. `redis://HOST[:PORT]`) | |
|
||||||
| `--redis-insecure-skip-tls-verify` | bool | skip TLS verification when connecting to Redis | false |
|
| `--redis-insecure-skip-tls-verify` | bool | skip TLS verification when connecting to Redis | false |
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ type OAuthProxy struct {
|
||||||
allowedRoutes []allowedRoute
|
allowedRoutes []allowedRoute
|
||||||
apiRoutes []apiRoute
|
apiRoutes []apiRoute
|
||||||
redirectURL *url.URL // the url to receive requests at
|
redirectURL *url.URL // the url to receive requests at
|
||||||
|
relativeRedirectURL bool
|
||||||
whitelistDomains []string
|
whitelistDomains []string
|
||||||
provider providers.Provider
|
provider providers.Provider
|
||||||
sessionStore sessionsapi.SessionStore
|
sessionStore sessionsapi.SessionStore
|
||||||
|
|
@ -216,6 +217,7 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr
|
||||||
provider: provider,
|
provider: provider,
|
||||||
sessionStore: sessionStore,
|
sessionStore: sessionStore,
|
||||||
redirectURL: redirectURL,
|
redirectURL: redirectURL,
|
||||||
|
relativeRedirectURL: opts.RelativeRedirectURL,
|
||||||
apiRoutes: apiRoutes,
|
apiRoutes: apiRoutes,
|
||||||
allowedRoutes: allowedRoutes,
|
allowedRoutes: allowedRoutes,
|
||||||
whitelistDomains: opts.WhitelistDomains,
|
whitelistDomains: opts.WhitelistDomains,
|
||||||
|
|
@ -1018,7 +1020,7 @@ func prepareNoCacheMiddleware(next http.Handler) http.Handler {
|
||||||
// This is usually the OAuthProxy callback URL.
|
// This is usually the OAuthProxy callback URL.
|
||||||
func (p *OAuthProxy) getOAuthRedirectURI(req *http.Request) string {
|
func (p *OAuthProxy) getOAuthRedirectURI(req *http.Request) string {
|
||||||
// if `p.redirectURL` already has a host, return it
|
// if `p.redirectURL` already has a host, return it
|
||||||
if p.redirectURL.Host != "" {
|
if p.relativeRedirectURL || p.redirectURL.Host != "" {
|
||||||
return p.redirectURL.String()
|
return p.redirectURL.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3257,3 +3257,90 @@ func TestAuthOnlyAllowedEmails(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetOAuthRedirectURI(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
setupOpts func(*options.Options) *options.Options
|
||||||
|
req *http.Request
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "redirect with https schema",
|
||||||
|
setupOpts: func(baseOpts *options.Options) *options.Options {
|
||||||
|
return baseOpts
|
||||||
|
},
|
||||||
|
req: &http.Request{
|
||||||
|
Host: "example",
|
||||||
|
URL: &url.URL{
|
||||||
|
Scheme: schemeHTTPS,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: "https://example/oauth2/callback",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "redirect with http schema",
|
||||||
|
setupOpts: func(baseOpts *options.Options) *options.Options {
|
||||||
|
baseOpts.Cookie.Secure = false
|
||||||
|
return baseOpts
|
||||||
|
},
|
||||||
|
req: &http.Request{
|
||||||
|
Host: "example",
|
||||||
|
URL: &url.URL{
|
||||||
|
Scheme: schemeHTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: "http://example/oauth2/callback",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "relative redirect url",
|
||||||
|
setupOpts: func(baseOpts *options.Options) *options.Options {
|
||||||
|
baseOpts.RelativeRedirectURL = true
|
||||||
|
return baseOpts
|
||||||
|
},
|
||||||
|
req: &http.Request{},
|
||||||
|
want: "/oauth2/callback",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "proxy prefix",
|
||||||
|
setupOpts: func(baseOpts *options.Options) *options.Options {
|
||||||
|
baseOpts.ProxyPrefix = "/prefix"
|
||||||
|
return baseOpts
|
||||||
|
},
|
||||||
|
req: &http.Request{
|
||||||
|
Host: "example",
|
||||||
|
URL: &url.URL{
|
||||||
|
Scheme: schemeHTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: "https://example/prefix/callback",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "proxy prefix with relative redirect",
|
||||||
|
setupOpts: func(baseOpts *options.Options) *options.Options {
|
||||||
|
baseOpts.ProxyPrefix = "/prefix"
|
||||||
|
baseOpts.RelativeRedirectURL = true
|
||||||
|
return baseOpts
|
||||||
|
},
|
||||||
|
req: &http.Request{
|
||||||
|
Host: "example",
|
||||||
|
URL: &url.URL{
|
||||||
|
Scheme: schemeHTTP,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: "/prefix/callback",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
baseOpts := baseTestOptions()
|
||||||
|
err := validation.Validate(baseOpts)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
proxy, err := NewOAuthProxy(tt.setupOpts(baseOpts), func(string) bool { return true })
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equalf(t, tt.want, proxy.getOAuthRedirectURI(tt.req), "getOAuthRedirectURI(%v)", tt.req)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,16 @@ type SignatureData struct {
|
||||||
// Options holds Configuration Options that can be set by Command Line Flag,
|
// Options holds Configuration Options that can be set by Command Line Flag,
|
||||||
// or Config File
|
// or Config File
|
||||||
type Options struct {
|
type Options struct {
|
||||||
ProxyPrefix string `flag:"proxy-prefix" cfg:"proxy_prefix"`
|
ProxyPrefix string `flag:"proxy-prefix" cfg:"proxy_prefix"`
|
||||||
PingPath string `flag:"ping-path" cfg:"ping_path"`
|
PingPath string `flag:"ping-path" cfg:"ping_path"`
|
||||||
PingUserAgent string `flag:"ping-user-agent" cfg:"ping_user_agent"`
|
PingUserAgent string `flag:"ping-user-agent" cfg:"ping_user_agent"`
|
||||||
ReadyPath string `flag:"ready-path" cfg:"ready_path"`
|
ReadyPath string `flag:"ready-path" cfg:"ready_path"`
|
||||||
ReverseProxy bool `flag:"reverse-proxy" cfg:"reverse_proxy"`
|
ReverseProxy bool `flag:"reverse-proxy" cfg:"reverse_proxy"`
|
||||||
RealClientIPHeader string `flag:"real-client-ip-header" cfg:"real_client_ip_header"`
|
RealClientIPHeader string `flag:"real-client-ip-header" cfg:"real_client_ip_header"`
|
||||||
TrustedIPs []string `flag:"trusted-ip" cfg:"trusted_ips"`
|
TrustedIPs []string `flag:"trusted-ip" cfg:"trusted_ips"`
|
||||||
ForceHTTPS bool `flag:"force-https" cfg:"force_https"`
|
ForceHTTPS bool `flag:"force-https" cfg:"force_https"`
|
||||||
RawRedirectURL string `flag:"redirect-url" cfg:"redirect_url"`
|
RawRedirectURL string `flag:"redirect-url" cfg:"redirect_url"`
|
||||||
|
RelativeRedirectURL bool `flag:"relative-redirect-url" cfg:"relative_redirect_url"`
|
||||||
|
|
||||||
AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file"`
|
AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file"`
|
||||||
EmailDomains []string `flag:"email-domain" cfg:"email_domains"`
|
EmailDomains []string `flag:"email-domain" cfg:"email_domains"`
|
||||||
|
|
@ -117,6 +118,7 @@ func NewFlagSet() *pflag.FlagSet {
|
||||||
flagSet.StringSlice("trusted-ip", []string{}, "list of IPs or CIDR ranges to allow to bypass authentication. WARNING: trusting by IP has inherent security flaws, read the configuration documentation for more information.")
|
flagSet.StringSlice("trusted-ip", []string{}, "list of IPs or CIDR ranges to allow to bypass authentication. WARNING: trusting by IP has inherent security flaws, read the configuration documentation for more information.")
|
||||||
flagSet.Bool("force-https", false, "force HTTPS redirect for HTTP requests")
|
flagSet.Bool("force-https", false, "force HTTPS redirect for HTTP requests")
|
||||||
flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
|
flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
|
||||||
|
flagSet.Bool("relative-redirect-url", false, "allow relative OAuth Redirect URL.")
|
||||||
flagSet.StringSlice("skip-auth-regex", []string{}, "(DEPRECATED for --skip-auth-route) bypass authentication for requests path's that match (may be given multiple times)")
|
flagSet.StringSlice("skip-auth-regex", []string{}, "(DEPRECATED for --skip-auth-route) bypass authentication for requests path's that match (may be given multiple times)")
|
||||||
flagSet.StringSlice("skip-auth-route", []string{}, "bypass authentication for requests that match the method & path. Format: method=path_regex OR method!=path_regex. For all methods: path_regex OR !=path_regex")
|
flagSet.StringSlice("skip-auth-route", []string{}, "bypass authentication for requests that match the method & path. Format: method=path_regex OR method!=path_regex. For all methods: path_regex OR !=path_regex")
|
||||||
flagSet.StringSlice("api-route", []string{}, "return HTTP 401 instead of redirecting to authentication server if token is not valid. Format: path_regex")
|
flagSet.StringSlice("api-route", []string{}, "return HTTP 401 instead of redirecting to authentication server if token is not valid. Format: path_regex")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue