diff --git a/README.md b/README.md index 17c748dcc..38a840a7d 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ Usage of oauth2_proxy: -profile-url="": Profile access endpoint -provider="google": OAuth provider -proxy-prefix="/oauth2": the url root path that this proxy should be nested under (e.g. //sign_in) + -redirect-option="/portal": "Redirect to somewhere other than root after authorization (e.g. https://internalapp.yourcompany.com/portal) -redeem-url="": Token redemption endpoint -redirect-url="": the OAuth Redirect URL. ie: "https://internalapp.yourcompany.com/oauth2/callback" -request-logging=true: Log requests to stdout diff --git a/main.go b/main.go index 3fe3961d0..ac8e164f5 100644 --- a/main.go +++ b/main.go @@ -50,7 +50,7 @@ func main() { flagSet.Bool("display-htpasswd-form", true, "display username / password login form if an htpasswd file is provided") flagSet.String("custom-templates-dir", "", "path to custom html templates") flagSet.String("proxy-prefix", "/oauth2", "the url root path that this proxy should be nested under (e.g. //sign_in)") - + flagSet.String("redirect-option", "/portal", "Redirect to somewhere other than root after authorization (e.g. https://internalapp.yourcompany.com/portal)") flagSet.String("cookie-name", "_oauth2_proxy", "the name of the cookie that the oauth_proxy creates") flagSet.String("cookie-secret", "", "the seed string for secure cookies") flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*") diff --git a/oauthproxy.go b/oauthproxy.go index 5a127055c..137f18d31 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -37,6 +37,7 @@ type OauthProxy struct { redirectUrl *url.URL // the url to receive requests at provider providers.Provider ProxyPrefix string + RedirectOption string SignInMessage string HtpasswdFile *HtpasswdFile DisplayHtpasswdForm bool @@ -158,6 +159,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { OauthCallbackPath: fmt.Sprintf("%s/callback", opts.ProxyPrefix), ProxyPrefix: opts.ProxyPrefix, + RedirectOption: opts.RedirectOption, provider: opts.provider, serveMux: serveMux, redirectUrl: redirectUrl, @@ -224,10 +226,13 @@ func (p *OauthProxy) MakeCookie(req *http.Request, value string, expiration time if value != "" { value = cookie.SignedValue(p.CookieSeed, p.CookieName, value, now) } + + path := p.RedirectOption + return &http.Cookie{ Name: p.CookieName, Value: value, - Path: "/", + Path: path, Domain: domain, HttpOnly: p.CookieHttpOnly, Secure: p.CookieSecure, @@ -304,7 +309,7 @@ func (p *OauthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code redirect_url := req.URL.RequestURI() if redirect_url == p.SignInPath { - redirect_url = "/" + redirect_url = p.RedirectOption } t := struct { @@ -352,7 +357,7 @@ func (p *OauthProxy) GetRedirect(req *http.Request) (string, error) { redirect := req.FormValue("rd") if redirect == "" { - redirect = "/" + redirect = p.RedirectOption } return redirect, err @@ -413,13 +418,14 @@ func (p *OauthProxy) SignIn(rw http.ResponseWriter, req *http.Request) { } func (p *OauthProxy) OauthStart(rw http.ResponseWriter, req *http.Request) { - redirect, err := p.GetRedirect(req) + redirectOption, err := p.GetRedirect(req) if err != nil { p.ErrorPage(rw, 500, "Internal Error", err.Error()) return } redirectURI := p.GetRedirectURI(req.Host) - http.Redirect(rw, req, p.provider.GetLoginURL(redirectURI, redirect), 302) + redirectOption = p.RedirectOption + http.Redirect(rw, req, p.provider.GetLoginURL(redirectURI, redirectOption), 302) } func (p *OauthProxy) OauthCallback(rw http.ResponseWriter, req *http.Request) { @@ -446,7 +452,7 @@ func (p *OauthProxy) OauthCallback(rw http.ResponseWriter, req *http.Request) { redirect := req.Form.Get("state") if redirect == "" { - redirect = "/" + redirect = p.RedirectOption } // set cookie, or deny diff --git a/options.go b/options.go index b4b8afa43..799c01176 100644 --- a/options.go +++ b/options.go @@ -13,7 +13,8 @@ import ( // Configuration Options that can be set by Command Line Flag, or Config File type Options struct { - ProxyPrefix string `flag:"proxy-prefix" cfg:"proxy-prefix"` + ProxyPrefix string `flag:"proxy-prefix" cfg:"proxy_prefix"` + RedirectOption string `flag:"redirect-option" cfg:"redirect_option"` HttpAddress string `flag:"http-address" cfg:"http_address"` HttpsAddress string `flag:"https-address" cfg:"https_address"` RedirectUrl string `flag:"redirect-url" cfg:"redirect_url"` @@ -69,6 +70,7 @@ type Options struct { func NewOptions() *Options { return &Options{ + RedirectOption: "/", ProxyPrefix: "/oauth2", HttpAddress: "127.0.0.1:4180", HttpsAddress: ":443", diff --git a/providers/provider_default.go b/providers/provider_default.go index 1a2e7f7ab..9a82c6cbc 100644 --- a/providers/provider_default.go +++ b/providers/provider_default.go @@ -8,7 +8,6 @@ import ( "io/ioutil" "net/http" "net/url" - "strings" "github.com/bitly/oauth2_proxy/cookie" ) @@ -75,7 +74,7 @@ func (p *ProviderData) Redeem(redirectUrl, code string) (s *SessionState, err er } // GetLoginURL with typical oauth parameters -func (p *ProviderData) GetLoginURL(redirectURI, finalRedirect string) string { +func (p *ProviderData) GetLoginURL(redirectURI, redirectOption string) string { var a url.URL a = *p.LoginUrl params, _ := url.ParseQuery(a.RawQuery) @@ -84,9 +83,7 @@ func (p *ProviderData) GetLoginURL(redirectURI, finalRedirect string) string { params.Add("scope", p.Scope) params.Set("client_id", p.ClientID) params.Set("response_type", "code") - if strings.HasPrefix(finalRedirect, "/") { - params.Add("state", finalRedirect) - } + params.Add("state", redirectOption) a.RawQuery = params.Encode() return a.String() }