You've already forked oauth2-proxy
mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-06-15 00:15:00 +02:00
Add set basic auth param (#413)
* addint redirect capability to sign_out * updating changelog * Add a new param to set the Authorization header to up-stream systems as Basic user:password * Resolving code review * mutual exclusiv changes for Basic and Bearer Authorization header * Fixed the merge mixup and comment error * Updated changelog and fixed typo * Adding the new entry in changelog Co-authored-by: Costel Moraru <costel.moraru-germany@ibm.com>
This commit is contained in:
@ -27,6 +27,7 @@
|
|||||||
- [#432](https://github.com/oauth2-proxy/oauth2-proxy/pull/432) Update ruby dependencies for documentation (@theobarberbany)
|
- [#432](https://github.com/oauth2-proxy/oauth2-proxy/pull/432) Update ruby dependencies for documentation (@theobarberbany)
|
||||||
- [#471](https://github.com/oauth2-proxy/oauth2-proxy/pull/471) Add logging in case of invalid redirects (@gargath)
|
- [#471](https://github.com/oauth2-proxy/oauth2-proxy/pull/471) Add logging in case of invalid redirects (@gargath)
|
||||||
- [#462](https://github.com/oauth2-proxy/oauth2-proxy/pull/462) Allow HTML in banner message (@eritikass).
|
- [#462](https://github.com/oauth2-proxy/oauth2-proxy/pull/462) Allow HTML in banner message (@eritikass).
|
||||||
|
- [#413](https://github.com/oauth2-proxy/oauth2-proxy/pull/413) Add -set-basic-auth param to set the Basic Authorization header for upstreams (@morarucostel).
|
||||||
|
|
||||||
# v5.1.0
|
# v5.1.0
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ An example [oauth2-proxy.cfg]({{ site.gitweb }}/contrib/oauth2-proxy.cfg.example
|
|||||||
| `-session-store-type` | string | [Session data storage backend](configuration/sessions); redis or cookie | cookie |
|
| `-session-store-type` | string | [Session data storage backend](configuration/sessions); redis or cookie | cookie |
|
||||||
| `-set-xauthrequest` | bool | set X-Auth-Request-User, X-Auth-Request-Email and X-Auth-Request-Preferred-Username response headers (useful in Nginx auth_request mode) | false |
|
| `-set-xauthrequest` | bool | set X-Auth-Request-User, X-Auth-Request-Email and X-Auth-Request-Preferred-Username response headers (useful in Nginx auth_request mode) | false |
|
||||||
| `-set-authorization-header` | bool | set Authorization Bearer response header (useful in Nginx auth_request mode) | false |
|
| `-set-authorization-header` | bool | set Authorization Bearer response header (useful in Nginx auth_request mode) | false |
|
||||||
|
| `-set-basic-auth` | bool | set HTTP Basic Auth information in response (useful in Nginx auth_request mode) | true |
|
||||||
| `-signature-key` | string | GAP-Signature request signature key (algorithm:secretkey) | |
|
| `-signature-key` | string | GAP-Signature request signature key (algorithm:secretkey) | |
|
||||||
| `-silence-ping-logging` | bool | disable logging of requests to ping endpoint | false |
|
| `-silence-ping-logging` | bool | disable logging of requests to ping endpoint | false |
|
||||||
| `-skip-auth-preflight` | bool | will skip authentication for OPTIONS requests | false |
|
| `-skip-auth-preflight` | bool | will skip authentication for OPTIONS requests | false |
|
||||||
|
1
main.go
1
main.go
@ -43,6 +43,7 @@ func main() {
|
|||||||
flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
|
flagSet.Bool("set-xauthrequest", false, "set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode)")
|
||||||
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")
|
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")
|
||||||
flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
|
flagSet.Bool("pass-basic-auth", true, "pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream")
|
||||||
|
flagSet.Bool("set-basic-auth", true, "set HTTP Basic Auth information in response (useful in Nginx auth_request mode)")
|
||||||
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")
|
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")
|
||||||
flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
|
flagSet.Bool("pass-user-headers", true, "pass X-Forwarded-User and X-Forwarded-Email information to upstream")
|
||||||
flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header")
|
flagSet.String("basic-auth-password", "", "the password to set when passing the HTTP Basic Auth header")
|
||||||
|
@ -94,6 +94,7 @@ type OAuthProxy struct {
|
|||||||
serveMux http.Handler
|
serveMux http.Handler
|
||||||
SetXAuthRequest bool
|
SetXAuthRequest bool
|
||||||
PassBasicAuth bool
|
PassBasicAuth bool
|
||||||
|
SetBasicAuth bool
|
||||||
SkipProviderButton bool
|
SkipProviderButton bool
|
||||||
PassUserHeaders bool
|
PassUserHeaders bool
|
||||||
BasicAuthPassword string
|
BasicAuthPassword string
|
||||||
@ -302,6 +303,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
|
|||||||
compiledRegex: opts.CompiledRegex,
|
compiledRegex: opts.CompiledRegex,
|
||||||
SetXAuthRequest: opts.SetXAuthRequest,
|
SetXAuthRequest: opts.SetXAuthRequest,
|
||||||
PassBasicAuth: opts.PassBasicAuth,
|
PassBasicAuth: opts.PassBasicAuth,
|
||||||
|
SetBasicAuth: opts.SetBasicAuth,
|
||||||
PassUserHeaders: opts.PassUserHeaders,
|
PassUserHeaders: opts.PassUserHeaders,
|
||||||
BasicAuthPassword: opts.BasicAuthPassword,
|
BasicAuthPassword: opts.BasicAuthPassword,
|
||||||
PassAccessToken: opts.PassAccessToken,
|
PassAccessToken: opts.PassAccessToken,
|
||||||
@ -1037,6 +1039,14 @@ func (p *OAuthProxy) addHeadersForProxying(rw http.ResponseWriter, req *http.Req
|
|||||||
req.Header.Del("Authorization")
|
req.Header.Del("Authorization")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if p.SetBasicAuth {
|
||||||
|
if session.User != "" {
|
||||||
|
authVal := b64.StdEncoding.EncodeToString([]byte(session.User + ":" + p.BasicAuthPassword))
|
||||||
|
rw.Header().Set("Authorization", "Basic "+authVal)
|
||||||
|
} else {
|
||||||
|
rw.Header().Del("Authorization")
|
||||||
|
}
|
||||||
|
}
|
||||||
if p.SetAuthorization {
|
if p.SetAuthorization {
|
||||||
if session.IDToken != "" {
|
if session.IDToken != "" {
|
||||||
rw.Header().Set("Authorization", fmt.Sprintf("Bearer %s", session.IDToken))
|
rw.Header().Set("Authorization", fmt.Sprintf("Bearer %s", session.IDToken))
|
||||||
|
@ -404,6 +404,7 @@ func TestBasicAuthPassword(t *testing.T) {
|
|||||||
opts.ClientSecret = "alkgret"
|
opts.ClientSecret = "alkgret"
|
||||||
opts.CookieSecure = false
|
opts.CookieSecure = false
|
||||||
opts.PassBasicAuth = true
|
opts.PassBasicAuth = true
|
||||||
|
opts.SetBasicAuth = true
|
||||||
opts.PassUserHeaders = true
|
opts.PassUserHeaders = true
|
||||||
opts.PreferEmailToUser = true
|
opts.PreferEmailToUser = true
|
||||||
opts.BasicAuthPassword = "This is a secure password"
|
opts.BasicAuthPassword = "This is a secure password"
|
||||||
@ -1075,6 +1076,71 @@ func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
|
|||||||
assert.Equal(t, "oauth_user@example.com", pcTest.rw.HeaderMap["X-Auth-Request-Email"][0])
|
assert.Equal(t, "oauth_user@example.com", pcTest.rw.HeaderMap["X-Auth-Request-Email"][0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAuthOnlyEndpointSetBasicAuthTrueRequestHeaders(t *testing.T) {
|
||||||
|
var pcTest ProcessCookieTest
|
||||||
|
|
||||||
|
pcTest.opts = NewOptions()
|
||||||
|
pcTest.opts.SetXAuthRequest = true
|
||||||
|
pcTest.opts.SetBasicAuth = true
|
||||||
|
pcTest.opts.Validate()
|
||||||
|
|
||||||
|
pcTest.proxy = NewOAuthProxy(pcTest.opts, func(email string) bool {
|
||||||
|
return pcTest.validateUser
|
||||||
|
})
|
||||||
|
pcTest.proxy.provider = &TestProvider{
|
||||||
|
ValidToken: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
pcTest.validateUser = true
|
||||||
|
|
||||||
|
pcTest.rw = httptest.NewRecorder()
|
||||||
|
pcTest.req, _ = http.NewRequest("GET",
|
||||||
|
pcTest.opts.ProxyPrefix+"/auth", nil)
|
||||||
|
|
||||||
|
startSession := &sessions.SessionState{
|
||||||
|
User: "oauth_user", Email: "oauth_user@example.com", AccessToken: "oauth_token", CreatedAt: time.Now()}
|
||||||
|
pcTest.SaveSession(startSession)
|
||||||
|
|
||||||
|
pcTest.proxy.ServeHTTP(pcTest.rw, pcTest.req)
|
||||||
|
assert.Equal(t, http.StatusAccepted, pcTest.rw.Code)
|
||||||
|
assert.Equal(t, "oauth_user", pcTest.rw.HeaderMap["X-Auth-Request-User"][0])
|
||||||
|
assert.Equal(t, "oauth_user@example.com", pcTest.rw.HeaderMap["X-Auth-Request-Email"][0])
|
||||||
|
expectedHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte("oauth_user:"+pcTest.opts.BasicAuthPassword))
|
||||||
|
assert.Equal(t, expectedHeader, pcTest.rw.HeaderMap["Authorization"][0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAuthOnlyEndpointSetBasicAuthFalseRequestHeaders(t *testing.T) {
|
||||||
|
var pcTest ProcessCookieTest
|
||||||
|
|
||||||
|
pcTest.opts = NewOptions()
|
||||||
|
pcTest.opts.SetXAuthRequest = true
|
||||||
|
pcTest.opts.SetBasicAuth = false
|
||||||
|
pcTest.opts.Validate()
|
||||||
|
|
||||||
|
pcTest.proxy = NewOAuthProxy(pcTest.opts, func(email string) bool {
|
||||||
|
return pcTest.validateUser
|
||||||
|
})
|
||||||
|
pcTest.proxy.provider = &TestProvider{
|
||||||
|
ValidToken: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
pcTest.validateUser = true
|
||||||
|
|
||||||
|
pcTest.rw = httptest.NewRecorder()
|
||||||
|
pcTest.req, _ = http.NewRequest("GET",
|
||||||
|
pcTest.opts.ProxyPrefix+"/auth", nil)
|
||||||
|
|
||||||
|
startSession := &sessions.SessionState{
|
||||||
|
User: "oauth_user", Email: "oauth_user@example.com", AccessToken: "oauth_token", CreatedAt: time.Now()}
|
||||||
|
pcTest.SaveSession(startSession)
|
||||||
|
|
||||||
|
pcTest.proxy.ServeHTTP(pcTest.rw, pcTest.req)
|
||||||
|
assert.Equal(t, http.StatusAccepted, pcTest.rw.Code)
|
||||||
|
assert.Equal(t, "oauth_user", pcTest.rw.HeaderMap["X-Auth-Request-User"][0])
|
||||||
|
assert.Equal(t, "oauth_user@example.com", pcTest.rw.HeaderMap["X-Auth-Request-Email"][0])
|
||||||
|
assert.Equal(t, 0, len(pcTest.rw.HeaderMap["Authorization"]), "should not have Authorization header entries")
|
||||||
|
}
|
||||||
|
|
||||||
func TestAuthSkippedForPreflightRequests(t *testing.T) {
|
func TestAuthSkippedForPreflightRequests(t *testing.T) {
|
||||||
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
|
@ -73,6 +73,7 @@ type Options struct {
|
|||||||
SkipJwtBearerTokens bool `flag:"skip-jwt-bearer-tokens" cfg:"skip_jwt_bearer_tokens" env:"OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS"`
|
SkipJwtBearerTokens bool `flag:"skip-jwt-bearer-tokens" cfg:"skip_jwt_bearer_tokens" env:"OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS"`
|
||||||
ExtraJwtIssuers []string `flag:"extra-jwt-issuers" cfg:"extra_jwt_issuers" env:"OAUTH2_PROXY_EXTRA_JWT_ISSUERS"`
|
ExtraJwtIssuers []string `flag:"extra-jwt-issuers" cfg:"extra_jwt_issuers" env:"OAUTH2_PROXY_EXTRA_JWT_ISSUERS"`
|
||||||
PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth" env:"OAUTH2_PROXY_PASS_BASIC_AUTH"`
|
PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth" env:"OAUTH2_PROXY_PASS_BASIC_AUTH"`
|
||||||
|
SetBasicAuth bool `flag:"set-basic-auth" cfg:"set_basic_auth" env:"OAUTH2_PROXY_SET_BASIC_AUTH"`
|
||||||
PreferEmailToUser bool `flag:"prefer-email-to-user" cfg:"prefer_email_to_user" env:"OAUTH2_PROXY_PREFER_EMAIL_TO_USER"`
|
PreferEmailToUser bool `flag:"prefer-email-to-user" cfg:"prefer_email_to_user" env:"OAUTH2_PROXY_PREFER_EMAIL_TO_USER"`
|
||||||
BasicAuthPassword string `flag:"basic-auth-password" cfg:"basic_auth_password" env:"OAUTH2_PROXY_BASIC_AUTH_PASSWORD"`
|
BasicAuthPassword string `flag:"basic-auth-password" cfg:"basic_auth_password" env:"OAUTH2_PROXY_BASIC_AUTH_PASSWORD"`
|
||||||
PassAccessToken bool `flag:"pass-access-token" cfg:"pass_access_token" env:"OAUTH2_PROXY_PASS_ACCESS_TOKEN"`
|
PassAccessToken bool `flag:"pass-access-token" cfg:"pass_access_token" env:"OAUTH2_PROXY_PASS_ACCESS_TOKEN"`
|
||||||
@ -166,6 +167,7 @@ func NewOptions() *Options {
|
|||||||
SetXAuthRequest: false,
|
SetXAuthRequest: false,
|
||||||
SkipAuthPreflight: false,
|
SkipAuthPreflight: false,
|
||||||
PassBasicAuth: true,
|
PassBasicAuth: true,
|
||||||
|
SetBasicAuth: false,
|
||||||
PassUserHeaders: true,
|
PassUserHeaders: true,
|
||||||
PassAccessToken: false,
|
PassAccessToken: false,
|
||||||
PassHostHeader: true,
|
PassHostHeader: true,
|
||||||
@ -243,6 +245,10 @@ func (o *Options) Validate() error {
|
|||||||
"\n use email-domain=* to authorize all email addresses")
|
"\n use email-domain=* to authorize all email addresses")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.SetBasicAuth && o.SetAuthorization {
|
||||||
|
msgs = append(msgs, "mutually exclusive: set-basic-auth and set-authorization-header can not both be true")
|
||||||
|
}
|
||||||
|
|
||||||
if o.OIDCIssuerURL != "" {
|
if o.OIDCIssuerURL != "" {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
Reference in New Issue
Block a user