From 68d416489760788db84e1dd315d54101f2fcb2dd Mon Sep 17 00:00:00 2001 From: Joel Speed Date: Sat, 27 Jan 2018 10:14:19 +0000 Subject: [PATCH] Add Authorization header flags --- main.go | 2 ++ oauthproxy.go | 12 +++++++++++- options.go | 4 ++++ providers/google.go | 1 + providers/oidc.go | 1 + providers/session_state.go | 1 + 6 files changed, 20 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index c1cde80..5cfa1f5 100644 --- a/main.go +++ b/main.go @@ -37,6 +37,8 @@ func main() { flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header") flagSet.Bool("pass-access-token", false, "pass OAuth access_token to upstream via X-Forwarded-Access-Token header") flagSet.Bool("pass-host-header", true, "pass the request Host Header to upstream") + flagSet.Bool("pass-authorization-header", false, "pass the Authorization Header to upstream") + flagSet.Bool("set-authorization-header", false, "set Authorization response headers (useful in Nginx auth_request mode)") flagSet.Var(&skipAuthRegex, "skip-auth-regex", "bypass authentication for requests path's that match (may be given multiple times)") flagSet.Bool("skip-provider-button", false, "will skip sign-in-page to directly reach the next step: oauth/start") flagSet.Bool("skip-auth-preflight", false, "will skip authentication for OPTIONS requests") diff --git a/oauthproxy.go b/oauthproxy.go index 96d8c86..9a45120 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -76,6 +76,8 @@ type OAuthProxy struct { PassUserHeaders bool BasicAuthPassword string PassAccessToken bool + SetAuthorization bool + PassAuthorization bool CookieCipher *cookie.Cipher skipAuthRegex []string skipAuthPreflight bool @@ -183,7 +185,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { log.Printf("Cookie settings: name:%s secure(https):%v httponly:%v expiry:%s domain:%s refresh:%s", opts.CookieName, opts.CookieSecure, opts.CookieHTTPOnly, opts.CookieExpire, opts.CookieDomain, refresh) var cipher *cookie.Cipher - if opts.PassAccessToken || (opts.CookieRefresh != time.Duration(0)) { + if opts.PassAccessToken || opts.SetAuthorization || opts.PassAuthorization || (opts.CookieRefresh != time.Duration(0)) { var err error cipher, err = cookie.NewCipher(secretBytes(opts.CookieSecret)) if err != nil { @@ -222,6 +224,8 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy { PassUserHeaders: opts.PassUserHeaders, BasicAuthPassword: opts.BasicAuthPassword, PassAccessToken: opts.PassAccessToken, + SetAuthorization: opts.SetAuthorization, + PassAuthorization: opts.PassAuthorization, SkipProviderButton: opts.SkipProviderButton, CookieCipher: cipher, templates: loadTemplates(opts.CustomTemplatesDir), @@ -750,6 +754,12 @@ func (p *OAuthProxy) Authenticate(rw http.ResponseWriter, req *http.Request) int if p.PassAccessToken && session.AccessToken != "" { req.Header["X-Forwarded-Access-Token"] = []string{session.AccessToken} } + if p.PassAuthorization && session.IDToken != "" { + req.Header["Authorization"] = []string{fmt.Sprintf("Bearer %s", session.IDToken)} + } + if p.SetAuthorization && session.IDToken != "" { + rw.Header().Set("Authorization", fmt.Sprintf("Bearer %s", session.IDToken)) + } if session.Email == "" { rw.Header().Set("GAP-Auth", session.User) } else { diff --git a/options.go b/options.go index bb412d2..9696144 100644 --- a/options.go +++ b/options.go @@ -61,6 +61,8 @@ type Options struct { PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"` SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"` SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest"` + SetAuthorization bool `flag:"set-authorization-header" cfg:"set_authorization_header"` + PassAuthorization bool `flag:"pass-authorization-header" cfg:"pass_authorization_header"` SkipAuthPreflight bool `flag:"skip-auth-preflight" cfg:"skip_auth_preflight"` // These options allow for other providers besides Google, with @@ -113,6 +115,8 @@ func NewOptions() *Options { PassUserHeaders: true, PassAccessToken: false, PassHostHeader: true, + SetAuthorization: false, + PassAuthorization: false, ApprovalPrompt: "force", RequestLogging: true, RequestLoggingFormat: defaultRequestLoggingFormat, diff --git a/providers/google.go b/providers/google.go index 36283f2..feea36f 100644 --- a/providers/google.go +++ b/providers/google.go @@ -145,6 +145,7 @@ func (p *GoogleProvider) Redeem(redirectURL, code string) (s *SessionState, err } s = &SessionState{ AccessToken: jsonResponse.AccessToken, + IDToken: jsonResponse.IDToken, ExpiresOn: time.Now().Add(time.Duration(jsonResponse.ExpiresIn) * time.Second).Truncate(time.Second), RefreshToken: jsonResponse.RefreshToken, Email: email, diff --git a/providers/oidc.go b/providers/oidc.go index 9624826..364879c 100644 --- a/providers/oidc.go +++ b/providers/oidc.go @@ -68,6 +68,7 @@ func (p *OIDCProvider) Redeem(redirectURL, code string) (s *SessionState, err er s = &SessionState{ AccessToken: token.AccessToken, + IDToken: rawIDToken, RefreshToken: token.RefreshToken, ExpiresOn: token.Expiry, Email: claims.Email, diff --git a/providers/session_state.go b/providers/session_state.go index fcac6e9..8195029 100644 --- a/providers/session_state.go +++ b/providers/session_state.go @@ -12,6 +12,7 @@ import ( // SessionState is used to store information about the currently authenticated user session type SessionState struct { AccessToken string + IDToken string ExpiresOn time.Time RefreshToken string Email string