make redirect_uri optional
This commit is contained in:
		
							parent
							
								
									748247dde1
								
							
						
					
					
						commit
						ebae065b11
					
				|  | @ -117,7 +117,6 @@ The command line to run `google_auth_proxy` would look like this: | ||||||
| 
 | 
 | ||||||
| ```bash | ```bash | ||||||
| ./google_auth_proxy \ | ./google_auth_proxy \ | ||||||
|    --redirect-url="https://internal.yourcompany.com/oauth2/callback"  \ |  | ||||||
|    --google-apps-domain="yourcompany.com"  \ |    --google-apps-domain="yourcompany.com"  \ | ||||||
|    --upstream=http://127.0.0.1:8080/ \ |    --upstream=http://127.0.0.1:8080/ \ | ||||||
|    --cookie-secret=... \ |    --cookie-secret=... \ | ||||||
|  | @ -134,4 +133,4 @@ Google Auth Proxy responds directly to the following endpoints. All other endpoi | ||||||
| * /ping - returns an 200 OK response | * /ping - returns an 200 OK response | ||||||
| * /oauth2/sign_in - the login page, which also doubles as a sign out page (it clears cookies) | * /oauth2/sign_in - the login page, which also doubles as a sign out page (it clears cookies) | ||||||
| * /oauth2/start - a URL that will redirect to start the OAuth cycle | * /oauth2/start - a URL that will redirect to start the OAuth cycle | ||||||
| * /oauth2/callback - the URL used at the end of the OAuth cycle | * /oauth2/callback - the URL used at the end of the OAuth cycle. The oauth app will be configured with this ass the callback url. | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| # http_address = "127.0.0.1:4180" | # http_address = "127.0.0.1:4180" | ||||||
| 
 | 
 | ||||||
| ## the OAuth Redirect URL. | ## the OAuth Redirect URL. | ||||||
|  | # defaults to the "https://" + requested host header + "/oauth2/callback" | ||||||
| # redirect_url = "https://internalapp.yourcompany.com/oauth2/callback" | # redirect_url = "https://internalapp.yourcompany.com/oauth2/callback" | ||||||
| 
 | 
 | ||||||
| ## the http url(s) of the upstream endpoint. If multiple, routing is based on path | ## the http url(s) of the upstream endpoint. If multiple, routing is based on path | ||||||
|  |  | ||||||
|  | @ -98,7 +98,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { | ||||||
| 	if domain == "" { | 	if domain == "" { | ||||||
| 		domain = "<default>" | 		domain = "<default>" | ||||||
| 	} | 	} | ||||||
| 	log.Printf("Cookie settings: https_only: %v httponly: %v expiry: %s domain:%s", opts.CookieHttpsOnly, opts.CookieHttpOnly, opts.CookieExpire, domain) | 	log.Printf("Cookie settings: https_only (SSL required): %v httponly: %v expiry: %s domain:%s", opts.CookieHttpsOnly, opts.CookieHttpOnly, opts.CookieExpire, domain) | ||||||
| 	return &OauthProxy{ | 	return &OauthProxy{ | ||||||
| 		CookieKey:       "_oauthproxy", | 		CookieKey:       "_oauthproxy", | ||||||
| 		CookieSeed:      opts.CookieSecret, | 		CookieSeed:      opts.CookieSecret, | ||||||
|  | @ -122,15 +122,33 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *OauthProxy) GetLoginURL(redirectUrl string) string { | func (p *OauthProxy) GetRedirectUrl(host string) string { | ||||||
|  | 	// default to the request Host if not set
 | ||||||
|  | 	if p.redirectUrl.Host != "" { | ||||||
|  | 		return p.redirectUrl.String() | ||||||
|  | 	} | ||||||
|  | 	var u url.URL | ||||||
|  | 	u = *p.redirectUrl | ||||||
|  | 	if u.Scheme == "" { | ||||||
|  | 		if p.CookieHttpsOnly { | ||||||
|  | 			u.Scheme = "https" | ||||||
|  | 		} else { | ||||||
|  | 			u.Scheme = "http" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	u.Host = host | ||||||
|  | 	return u.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (p *OauthProxy) GetLoginURL(host, redirect string) string { | ||||||
| 	params := url.Values{} | 	params := url.Values{} | ||||||
| 	params.Add("redirect_uri", p.redirectUrl.String()) | 	params.Add("redirect_uri", p.GetRedirectUrl(host)) | ||||||
| 	params.Add("approval_prompt", "force") | 	params.Add("approval_prompt", "force") | ||||||
| 	params.Add("scope", p.oauthScope) | 	params.Add("scope", p.oauthScope) | ||||||
| 	params.Add("client_id", p.clientID) | 	params.Add("client_id", p.clientID) | ||||||
| 	params.Add("response_type", "code") | 	params.Add("response_type", "code") | ||||||
| 	if strings.HasPrefix(redirectUrl, "/") { | 	if strings.HasPrefix(redirect, "/") { | ||||||
| 		params.Add("state", redirectUrl) | 		params.Add("state", redirect) | ||||||
| 	} | 	} | ||||||
| 	return fmt.Sprintf("%s?%s", p.oauthLoginUrl, params.Encode()) | 	return fmt.Sprintf("%s?%s", p.oauthLoginUrl, params.Encode()) | ||||||
| } | } | ||||||
|  | @ -161,12 +179,12 @@ func (p *OauthProxy) displayCustomLoginForm() bool { | ||||||
| 	return p.HtpasswdFile != nil && p.DisplayHtpasswdForm | 	return p.HtpasswdFile != nil && p.DisplayHtpasswdForm | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (p *OauthProxy) redeemCode(code string) (string, string, error) { | func (p *OauthProxy) redeemCode(host, code string) (string, string, error) { | ||||||
| 	if code == "" { | 	if code == "" { | ||||||
| 		return "", "", errors.New("missing code") | 		return "", "", errors.New("missing code") | ||||||
| 	} | 	} | ||||||
| 	params := url.Values{} | 	params := url.Values{} | ||||||
| 	params.Add("redirect_uri", p.redirectUrl.String()) | 	params.Add("redirect_uri", p.GetRedirectUrl(host)) | ||||||
| 	params.Add("client_id", p.clientID) | 	params.Add("client_id", p.clientID) | ||||||
| 	params.Add("client_secret", p.clientSecret) | 	params.Add("client_secret", p.clientSecret) | ||||||
| 	params.Add("code", code) | 	params.Add("code", code) | ||||||
|  | @ -370,7 +388,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | ||||||
| 			p.ErrorPage(rw, 500, "Internal Error", err.Error()) | 			p.ErrorPage(rw, 500, "Internal Error", err.Error()) | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		http.Redirect(rw, req, p.GetLoginURL(redirect), 302) | 		http.Redirect(rw, req, p.GetLoginURL(req.Host, redirect), 302) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if req.URL.Path == oauthCallbackPath { | 	if req.URL.Path == oauthCallbackPath { | ||||||
|  | @ -386,7 +404,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		_, email, err := p.redeemCode(req.Form.Get("code")) | 		_, email, err := p.redeemCode(req.Host, req.Form.Get("code")) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Printf("%s error redeeming code %s", remoteAddr, err) | 			log.Printf("%s error redeeming code %s", remoteAddr, err) | ||||||
| 			p.ErrorPage(rw, 500, "Internal Error", err.Error()) | 			p.ErrorPage(rw, 500, "Internal Error", err.Error()) | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ type Options struct { | ||||||
| 	CookieSecret    string        `flag:"cookie-secret" cfg:"cookie_secret" env:"GOOGLE_AUTH_PROXY_COOKIE_SECRET"` | 	CookieSecret    string        `flag:"cookie-secret" cfg:"cookie_secret" env:"GOOGLE_AUTH_PROXY_COOKIE_SECRET"` | ||||||
| 	CookieDomain    string        `flag:"cookie-domain" cfg:"cookie_domain" env:"GOOGLE_AUTH_PROXY_COOKIE_DOMAIN"` | 	CookieDomain    string        `flag:"cookie-domain" cfg:"cookie_domain" env:"GOOGLE_AUTH_PROXY_COOKIE_DOMAIN"` | ||||||
| 	CookieExpire    time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"GOOGLE_AUTH_PROXY_COOKIE_EXPIRE"` | 	CookieExpire    time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"GOOGLE_AUTH_PROXY_COOKIE_EXPIRE"` | ||||||
| 	CookieHttpsOnly bool          `flag:"cookie-https-only" cfg:"cookie_https_only"` | 	CookieHttpsOnly bool          `flag:"cookie-https-only" cfg:"cookie_https_only"` // set secure cookie flag
 | ||||||
| 	CookieHttpOnly  bool          `flag:"cookie-httponly" cfg:"cookie_httponly"` | 	CookieHttpOnly  bool          `flag:"cookie-httponly" cfg:"cookie_httponly"` | ||||||
| 
 | 
 | ||||||
| 	Upstreams      []string `flag:"upstream" cfg:"upstreams"` | 	Upstreams      []string `flag:"upstream" cfg:"upstreams"` | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue