diff --git a/main.go b/main.go index 2154407..0442cfa 100644 --- a/main.go +++ b/main.go @@ -38,6 +38,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 b25fbff..62b6eb1 100644 --- a/oauthproxy.go +++ b/oauthproxy.go @@ -67,6 +67,8 @@ type OAuthProxy struct { PassUserHeaders bool BasicAuthPassword string PassAccessToken bool + SetAuthorization bool + PassAuthorization bool CookieCipher *cookie.Cipher skipAuthRegex []string skipAuthPreflight bool @@ -164,7 +166,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 { @@ -204,6 +206,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), @@ -720,6 +724,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 504055e..1c2fe7d 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 @@ -111,6 +113,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 66406bd..026e90e 100644 --- a/providers/google.go +++ b/providers/google.go @@ -142,6 +142,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 0c0fa52..58adca0 100644 --- a/providers/oidc.go +++ b/providers/oidc.go @@ -65,6 +65,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 805c702..648208a 100644 --- a/providers/session_state.go +++ b/providers/session_state.go @@ -11,6 +11,7 @@ import ( type SessionState struct { AccessToken string + IdToken string ExpiresOn time.Time RefreshToken string Email string