git.iko.soy/typeable/oauth2-proxy
on master help sign in
Support the PreferEmailToUser option on PassUserHeaders
4cd43efJordan Crawford
CHANGELOG.md+1
@@ -18,6 +18,7 @@
18- [#355](https://github.com/pusher/oauth2_proxy/pull/355) Add Client Secret File support for providers that rotate client secret via file system (@pasha-r)
18- [#355](https://github.com/pusher/oauth2_proxy/pull/355) Add Client Secret File support for providers that rotate client secret via file system (@pasha-r)
19- [#401](https://github.com/pusher/oauth2_proxy/pull/401) Give the option to pass email address in the Basic auth header instead of upstream usernames. (@Spindel)
19- [#401](https://github.com/pusher/oauth2_proxy/pull/401) Give the option to pass email address in the Basic auth header instead of upstream usernames. (@Spindel)
20- [#405](https://github.com/pusher/oauth2_proxy/pull/405) The `/sign_in` page now honors the `rd` query parameter, fixing the redirect after a successful authentication (@ti-mo)
20- [#405](https://github.com/pusher/oauth2_proxy/pull/405) The `/sign_in` page now honors the `rd` query parameter, fixing the redirect after a successful authentication (@ti-mo)
21+- [#434](https://github.com/pusher/oauth2_proxy/pull/434) Give the option to prefer email address in the username header when using the -pass-user-headers option (@jordancrawfordnz)
21
22
22# v5.0.0
23# v5.0.0
23
24
docs/configuration/configuration.md+1−1
@@ -74,7 +74,7 @@ An example [oauth2_proxy.cfg]({{ site.gitweb }}/contrib/oauth2_proxy.cfg.example
74| `-pass-access-token` | bool | pass OAuth access_token to upstream via X-Forwarded-Access-Token header | false |
74| `-pass-access-token` | bool | pass OAuth access_token to upstream via X-Forwarded-Access-Token header | false |
75| `-pass-authorization-header` | bool | pass OIDC IDToken to upstream via Authorization Bearer header | false |
75| `-pass-authorization-header` | bool | pass OIDC IDToken to upstream via Authorization Bearer header | false |
76| `-pass-basic-auth` | bool | pass HTTP Basic Auth, X-Forwarded-User, X-Forwarded-Email and X-Forwarded-Preferred-Username information to upstream | true |
76| `-pass-basic-auth` | bool | pass HTTP Basic Auth, X-Forwarded-User, X-Forwarded-Email and X-Forwarded-Preferred-Username information to upstream | true |
77−| `-prefer-email-to-user` | bool | Prefer to use the Email address as the Username when passing information to upstream. Will only use Username if Email is unavailable, eg. htaccess authentication. | false |
77+| `-prefer-email-to-user` | bool | Prefer to use the Email address as the Username when passing information to upstream. Will only use Username if Email is unavailable, eg. htaccess authentication. Used in conjunction with `-pass-basic-auth` and `-pass-user-headers` | false |
78| `-pass-host-header` | bool | pass the request Host Header to upstream | true |
78| `-pass-host-header` | bool | pass the request Host Header to upstream | true |
79| `-pass-user-headers` | bool | pass X-Forwarded-User, X-Forwarded-Email and X-Forwarded-Preferred-Username information to upstream | true |
79| `-pass-user-headers` | bool | pass X-Forwarded-User, X-Forwarded-Email and X-Forwarded-Preferred-Username information to upstream | true |
80| `-profile-url` | string | Profile access endpoint | |
80| `-profile-url` | string | Profile access endpoint | |
main.go+1−1
@@ -41,7 +41,7 @@ func main() {
41 flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
41 flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
42 flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint, file:// paths for static files or static://<status_code> for static response. Routing is based on the path")
42 flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint, file:// paths for static files or static://<status_code> for static response. Routing is based on the path")
43 flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
43 flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
44− flagSet.Bool("prefer-email-to-user", false, "Prefer to use the Email address as the Username when passing information to upstream. Will only use Username if Email is unavailable, eg. htaccess authentication.")
44+ flagSet.Bool("prefer-email-to-user", false, "Prefer to use the Email address as the Username when passing information to upstream. Will only use Username if Email is unavailable, eg. htaccess authentication. Used in conjunction with -pass-basic-auth and -pass-user-headers")
45 flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
45 flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
46 flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header")
46 flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header")
47 flagSet.Bool("pass-access-token", false, "pass OAuth access_token to upstream via X-Forwarded-Access-Token header")
47 flagSet.Bool("pass-access-token", false, "pass OAuth access_token to upstream via X-Forwarded-Access-Token header")
oauthproxy.go+10−4
@@ -959,12 +959,18 @@ func (p *OAuthProxy) addHeadersForProxying(rw http.ResponseWriter, req *http.Req
959 }
959 }
960
960
961 if p.PassUserHeaders {
961 if p.PassUserHeaders {
962− req.Header["X-Forwarded-User"] = []string{session.User}
963− if session.Email != "" {
962+ if p.PreferEmailToUser && session.Email != "" {
964− req.Header["X-Forwarded-Email"] = []string{session.Email}
963+ req.Header["X-Forwarded-User"] = []string{session.Email}
965− } else {
966 req.Header.Del("X-Forwarded-Email")
964 req.Header.Del("X-Forwarded-Email")
965+ } else {
966+ req.Header["X-Forwarded-User"] = []string{session.User}
967+ if session.Email != "" {
968+ req.Header["X-Forwarded-Email"] = []string{session.Email}
969+ } else {
970+ req.Header.Del("X-Forwarded-Email")
971+ }
967 }
972 }
973+
968 if session.PreferredUsername != "" {
974 if session.PreferredUsername != "" {
969 req.Header["X-Forwarded-Preferred-Username"] = []string{session.PreferredUsername}
975 req.Header["X-Forwarded-Preferred-Username"] = []string{session.PreferredUsername}
970 } else {
976 } else {
oauthproxy_test.go+29−7
@@ -511,23 +511,45 @@ func TestBasicAuthWithEmail(t *testing.T) {
511 assert.Equal(t, expectedEmailHeader, req.Header["Authorization"][0])
511 assert.Equal(t, expectedEmailHeader, req.Header["Authorization"][0])
512 assert.Equal(t, emailAddress, req.Header["X-Forwarded-User"][0])
512 assert.Equal(t, emailAddress, req.Header["X-Forwarded-User"][0])
513 }
513 }
514+}
514
515
516+func TestPassUserHeadersWithEmail(t *testing.T) {
517+ opts := NewOptions()
518+ opts.PassBasicAuth = false
515 opts.PassUserHeaders = true
519 opts.PassUserHeaders = true
520+ opts.PreferEmailToUser = false
521+ opts.Validate()
522+
523+ const emailAddress = "john.doe@example.com"
524+ const userName = "9fcab5c9b889a557"
525+
526+ session := &sessions.SessionState{
527+ User: userName,
528+ Email: emailAddress,
529+ AccessToken: "oauth_token",
530+ CreatedAt: time.Now(),
531+ }
516 {
532 {
517− // PassUserHeaders takes predecense over the headers added by
518− // PassBasicAuth, thus we expect them to contain something else.
519 rw := httptest.NewRecorder()
533 rw := httptest.NewRecorder()
520− req, _ := http.NewRequest("GET", opts.ProxyPrefix+"/testCase2", nil)
534+ req, _ := http.NewRequest("GET", opts.ProxyPrefix+"/testCase0", nil)
521 proxy := NewOAuthProxy(opts, func(email string) bool {
535 proxy := NewOAuthProxy(opts, func(email string) bool {
522 return email == emailAddress
536 return email == emailAddress
523 })
537 })
524−
525 proxy.addHeadersForProxying(rw, req, session)
538 proxy.addHeadersForProxying(rw, req, session)
526− // The user address here should still be an email.
527− assert.Equal(t, expectedEmailHeader, req.Header["Authorization"][0])
528− assert.Equal(t, emailAddress, req.Header["X-Forwarded-Email"][0])
529 assert.Equal(t, userName, req.Header["X-Forwarded-User"][0])
539 assert.Equal(t, userName, req.Header["X-Forwarded-User"][0])
530 }
540 }
541+
542+ opts.PreferEmailToUser = true
543+ {
544+ rw := httptest.NewRecorder()
545+ req, _ := http.NewRequest("GET", opts.ProxyPrefix+"/testCase1", nil)
546+
547+ proxy := NewOAuthProxy(opts, func(email string) bool {
548+ return email == emailAddress
549+ })
550+ proxy.addHeadersForProxying(rw, req, session)
551+ assert.Equal(t, emailAddress, req.Header["X-Forwarded-User"][0])
552+ }
531}
553}
532
554
533type PassAccessTokenTest struct {
555type PassAccessTokenTest struct {
options.go+2−2
@@ -281,8 +281,8 @@ func (o *Options) Validate() error {
281 }
281 }
282 }
282 }
283
283
284− if o.PreferEmailToUser == true && o.PassBasicAuth == false {
284+ if o.PreferEmailToUser == true && o.PassBasicAuth == false && o.PassUserHeaders == false {
285− msgs = append(msgs, "PreferEmailToUser should only be used with PassBasicAuth")
285+ msgs = append(msgs, "PreferEmailToUser should only be used with PassBasicAuth or PassUserHeaders")
286 }
286 }
287
287
288 if o.SkipJwtBearerTokens {
288 if o.SkipJwtBearerTokens {