git.iko.soy/typeable/oauth2-proxy
on master help sign in
make redirect_uri optional
commitebae065b115fa60b8180930d366cdd0e4395968e authorJehiah Czebotar <jehiah@gmail.com> dateTue 17 Mar 2015, 16:25 (12 years ago) parent748247d
4 files changed+30−12
README.md+1−2 contrib/google_auth_proxy.cfg.example+1 oauthproxy.go+27−9 options.go+1−1
README.md+1−2
@@ -117,7 +117,6 @@ The command line to run `google_auth_proxy` would look like this:
117117
118118```bash
119119./google_auth_proxy \
120− --redirect-url="https://internal.yourcompany.com/oauth2/callback" \
121120 --google-apps-domain="yourcompany.com" \
122121 --upstream=http://127.0.0.1:8080/ \
123122 --cookie-secret=... \
@@ -134,4 +133,4 @@ Google Auth Proxy responds directly to the following endpoints. All other endpoi
134133* /ping - returns an 200 OK response
135134* /oauth2/sign_in - the login page, which also doubles as a sign out page (it clears cookies)
136135* /oauth2/start - a URL that will redirect to start the OAuth cycle
137−* /oauth2/callback - the URL used at the end of the OAuth cycle
136+* /oauth2/callback - the URL used at the end of the OAuth cycle. The oauth app will be configured with this ass the callback url.
contrib/google_auth_proxy.cfg.example+1
@@ -5,6 +5,7 @@
55# http_address = "127.0.0.1:4180"
66
77## the OAuth Redirect URL.
8+# defaults to the "https://" + requested host header + "/oauth2/callback"
89# redirect_url = "https://internalapp.yourcompany.com/oauth2/callback"
910
1011## the http url(s) of the upstream endpoint. If multiple, routing is based on path
oauthproxy.go+27−9
@@ -98,7 +98,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
9898 if domain == "" {
9999 domain = "<default>"
100100 }
101− log.Printf("Cookie settings: https_only: %v httponly: %v expiry: %s domain:%s", opts.CookieHttpsOnly, opts.CookieHttpOnly, opts.CookieExpire, domain)
101+ log.Printf("Cookie settings: https_only (SSL required): %v httponly: %v expiry: %s domain:%s", opts.CookieHttpsOnly, opts.CookieHttpOnly, opts.CookieExpire, domain)
102102 return &OauthProxy{
103103 CookieKey: "_oauthproxy",
104104 CookieSeed: opts.CookieSecret,
@@ -122,15 +122,33 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
122122 }
123123}
124124
125−func (p *OauthProxy) GetLoginURL(redirectUrl string) string {
125+func (p *OauthProxy) GetRedirectUrl(host string) string {
126+ // default to the request Host if not set
127+ if p.redirectUrl.Host != "" {
128+ return p.redirectUrl.String()
129+ }
130+ var u url.URL
131+ u = *p.redirectUrl
132+ if u.Scheme == "" {
133+ if p.CookieHttpsOnly {
134+ u.Scheme = "https"
135+ } else {
136+ u.Scheme = "http"
137+ }
138+ }
139+ u.Host = host
140+ return u.String()
141+}
142+
143+func (p *OauthProxy) GetLoginURL(host, redirect string) string {
126144 params := url.Values{}
127− params.Add("redirect_uri", p.redirectUrl.String())
145+ params.Add("redirect_uri", p.GetRedirectUrl(host))
128146 params.Add("approval_prompt", "force")
129147 params.Add("scope", p.oauthScope)
130148 params.Add("client_id", p.clientID)
131149 params.Add("response_type", "code")
132− if strings.HasPrefix(redirectUrl, "/") {
133− params.Add("state", redirectUrl)
150+ if strings.HasPrefix(redirect, "/") {
151+ params.Add("state", redirect)
134152 }
135153 return fmt.Sprintf("%s?%s", p.oauthLoginUrl, params.Encode())
136154}
@@ -161,12 +179,12 @@ func (p *OauthProxy) displayCustomLoginForm() bool {
161179 return p.HtpasswdFile != nil && p.DisplayHtpasswdForm
162180}
163181
164−func (p *OauthProxy) redeemCode(code string) (string, string, error) {
182+func (p *OauthProxy) redeemCode(host, code string) (string, string, error) {
165183 if code == "" {
166184 return "", "", errors.New("missing code")
167185 }
168186 params := url.Values{}
169− params.Add("redirect_uri", p.redirectUrl.String())
187+ params.Add("redirect_uri", p.GetRedirectUrl(host))
170188 params.Add("client_id", p.clientID)
171189 params.Add("client_secret", p.clientSecret)
172190 params.Add("code", code)
@@ -370,7 +388,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
370388 p.ErrorPage(rw, 500, "Internal Error", err.Error())
371389 return
372390 }
373− http.Redirect(rw, req, p.GetLoginURL(redirect), 302)
391+ http.Redirect(rw, req, p.GetLoginURL(req.Host, redirect), 302)
374392 return
375393 }
376394 if req.URL.Path == oauthCallbackPath {
@@ -386,7 +404,7 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
386404 return
387405 }
388406
389− _, email, err := p.redeemCode(req.Form.Get("code"))
407+ _, email, err := p.redeemCode(req.Host, req.Form.Get("code"))
390408 if err != nil {
391409 log.Printf("%s error redeeming code %s", remoteAddr, err)
392410 p.ErrorPage(rw, 500, "Internal Error", err.Error())
options.go+1−1
@@ -24,7 +24,7 @@ type Options struct {
2424 CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret" env:"GOOGLE_AUTH_PROXY_COOKIE_SECRET"`
2525 CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain" env:"GOOGLE_AUTH_PROXY_COOKIE_DOMAIN"`
2626 CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"GOOGLE_AUTH_PROXY_COOKIE_EXPIRE"`
27− CookieHttpsOnly bool `flag:"cookie-https-only" cfg:"cookie_https_only"`
27+ CookieHttpsOnly bool `flag:"cookie-https-only" cfg:"cookie_https_only"` // set secure cookie flag
2828 CookieHttpOnly bool `flag:"cookie-httponly" cfg:"cookie_httponly"`
2929
3030 Upstreams []string `flag:"upstream" cfg:"upstreams"`