git.iko.soy/typeable/oauth2-proxy
on master help sign in
add --set-xauthrequest flag for use in Nginx auth_request mode
829b442Lukasz Siudut
@@ -30,6 +30,7 @@ func main() {
30 flagSet.String("tls-cert", "", "path to certificate file")
30 flagSet.String("tls-cert", "", "path to certificate file")
31 flagSet.String("tls-key", "", "path to private key file")
31 flagSet.String("tls-key", "", "path to private key file")
32 flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
32 flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
33+ flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
33 flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint or file:// paths for static files. Routing is based on the path")
34 flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint or file:// paths for static files. Routing is based on the path")
34 flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
35 flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
35 flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
36 flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
oauthproxy.go+8
@@ -60,6 +60,7 @@ type OAuthProxy struct {
60 HtpasswdFile *HtpasswdFile
60 HtpasswdFile *HtpasswdFile
61 DisplayHtpasswdForm bool
61 DisplayHtpasswdForm bool
62 serveMux http.Handler
62 serveMux http.Handler
63+ SetXAuthRequest bool
63 PassBasicAuth bool
64 PassBasicAuth bool
64 SkipProviderButton bool
65 SkipProviderButton bool
65 PassUserHeaders bool
66 PassUserHeaders bool
@@ -198,6 +199,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
198 redirectURL: redirectURL,
199 redirectURL: redirectURL,
199 skipAuthRegex: opts.SkipAuthRegex,
200 skipAuthRegex: opts.SkipAuthRegex,
200 compiledRegex: opts.CompiledRegex,
201 compiledRegex: opts.CompiledRegex,
202+ SetXAuthRequest: opts.SetXAuthRequest,
201 PassBasicAuth: opts.PassBasicAuth,
203 PassBasicAuth: opts.PassBasicAuth,
202 PassUserHeaders: opts.PassUserHeaders,
204 PassUserHeaders: opts.PassUserHeaders,
203 BasicAuthPassword: opts.BasicAuthPassword,
205 BasicAuthPassword: opts.BasicAuthPassword,
@@ -663,6 +665,12 @@ func (p *OAuthProxy) Authenticate(rw http.ResponseWriter, req *http.Request) int
663 req.Header["X-Forwarded-Email"] = []string{session.Email}
665 req.Header["X-Forwarded-Email"] = []string{session.Email}
664 }
666 }
665 }
667 }
668+ if p.SetXAuthRequest {
669+ rw.Header().Set("X-Auth-Request-User", session.User)
670+ if session.Email != "" {
671+ rw.Header().Set("X-Auth-Request-Email", session.Email)
672+ }
673+ }
666 if p.PassAccessToken && session.AccessToken != "" {
674 if p.PassAccessToken && session.AccessToken != "" {
667 req.Header["X-Forwarded-Access-Token"] = []string{session.AccessToken}
675 req.Header["X-Forwarded-Access-Token"] = []string{session.AccessToken}
668 }
676 }
oauthproxy_test.go+30
@@ -611,6 +611,36 @@ func TestAuthOnlyEndpointUnauthorizedOnEmailValidationFailure(t *testing.T) {
611 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
611 assert.Equal(t, "unauthorized request\n", string(bodyBytes))
612}
612}
613
613
614+func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
615+ var pc_test ProcessCookieTest
616+
617+ pc_test.opts = NewOptions()
618+ pc_test.opts.SetXAuthRequest = true
619+ pc_test.opts.Validate()
620+
621+ pc_test.proxy = NewOAuthProxy(pc_test.opts, func(email string) bool {
622+ return pc_test.validate_user
623+ })
624+ pc_test.proxy.provider = &TestProvider{
625+ ValidToken: true,
626+ }
627+
628+ pc_test.validate_user = true
629+
630+ pc_test.rw = httptest.NewRecorder()
631+ pc_test.req, _ = http.NewRequest("GET",
632+ pc_test.opts.ProxyPrefix+"/auth", nil)
633+
634+ startSession := &providers.SessionState{
635+ User: "oauth_user", Email: "oauth_user@example.com", AccessToken: "oauth_token"}
636+ pc_test.SaveSession(startSession, time.Now())
637+
638+ pc_test.proxy.ServeHTTP(pc_test.rw, pc_test.req)
639+ assert.Equal(t, http.StatusAccepted, pc_test.rw.Code)
640+ assert.Equal(t, "oauth_user", pc_test.rw.HeaderMap["X-Auth-Request-User"][0])
641+ assert.Equal(t, "oauth_user@example.com", pc_test.rw.HeaderMap["X-Auth-Request-Email"][0])
642+}
643+
614type SignatureAuthenticator struct {
644type SignatureAuthenticator struct {
615 auth hmacauth.HmacAuth
645 auth hmacauth.HmacAuth
616}
646}
options.go+2
@@ -57,6 +57,7 @@ type Options struct {
57 SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button"`
57 SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button"`
58 PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"`
58 PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"`
59 SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"`
59 SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"`
60+ SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest"`
60
61
61 // These options allow for other providers besides Google, with
62 // These options allow for other providers besides Google, with
62 // potential overrides.
63 // potential overrides.
@@ -97,6 +98,7 @@ func NewOptions() *Options {
97 CookieHttpOnly: true,
98 CookieHttpOnly: true,
98 CookieExpire: time.Duration(168) * time.Hour,
99 CookieExpire: time.Duration(168) * time.Hour,
99 CookieRefresh: time.Duration(0),
100 CookieRefresh: time.Duration(0),
101+ SetXAuthRequest: false,
100 PassBasicAuth: true,
102 PassBasicAuth: true,
101 PassUserHeaders: true,
103 PassUserHeaders: true,
102 PassAccessToken: false,
104 PassAccessToken: false,