Merge pull request #370 from idntfy/master
#369: Optionally allow skipping authentication for preflight requests
This commit is contained in:
commit
120a47a526
@ -199,6 +199,7 @@ Usage of oauth2_proxy:
|
|||||||
-scope="": Oauth scope specification
|
-scope="": Oauth scope specification
|
||||||
-signature-key="": GAP-Signature request signature key (algorithm:secretkey)
|
-signature-key="": GAP-Signature request signature key (algorithm:secretkey)
|
||||||
-skip-auth-regex=: bypass authentication for requests path's that match (may be given multiple times)
|
-skip-auth-regex=: bypass authentication for requests path's that match (may be given multiple times)
|
||||||
|
-skip-auth-preflight=false: bypass authentication for OPTIONAL requests so preflight requests could succeed when using CORS
|
||||||
-skip-provider-button=false: will skip sign-in-page to directly reach the next step: oauth/start
|
-skip-provider-button=false: will skip sign-in-page to directly reach the next step: oauth/start
|
||||||
-ssl-insecure-skip-verify: skip validation of certificates presented when using HTTPS
|
-ssl-insecure-skip-verify: skip validation of certificates presented when using HTTPS
|
||||||
-tls-cert="": path to certificate file
|
-tls-cert="": path to certificate file
|
||||||
|
1
main.go
1
main.go
@ -39,6 +39,7 @@ func main() {
|
|||||||
flagSet.Bool("pass-host-header", true, "pass the request Host Header to upstream")
|
flagSet.Bool("pass-host-header", true, "pass the request Host Header to upstream")
|
||||||
flagSet.Var(&skipAuthRegex, "skip-auth-regex", "bypass authentication for requests path's that match (may be given multiple times)")
|
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-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")
|
||||||
flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS")
|
flagSet.Bool("ssl-insecure-skip-verify", false, "skip validation of certificates presented when using HTTPS")
|
||||||
|
|
||||||
flagSet.Var(&emailDomains, "email-domain", "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")
|
flagSet.Var(&emailDomains, "email-domain", "authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email")
|
||||||
|
@ -68,6 +68,7 @@ type OAuthProxy struct {
|
|||||||
PassAccessToken bool
|
PassAccessToken bool
|
||||||
CookieCipher *cookie.Cipher
|
CookieCipher *cookie.Cipher
|
||||||
skipAuthRegex []string
|
skipAuthRegex []string
|
||||||
|
skipAuthPreflight bool
|
||||||
compiledRegex []*regexp.Regexp
|
compiledRegex []*regexp.Regexp
|
||||||
templates *template.Template
|
templates *template.Template
|
||||||
Footer string
|
Footer string
|
||||||
@ -198,6 +199,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
|
|||||||
serveMux: serveMux,
|
serveMux: serveMux,
|
||||||
redirectURL: redirectURL,
|
redirectURL: redirectURL,
|
||||||
skipAuthRegex: opts.SkipAuthRegex,
|
skipAuthRegex: opts.SkipAuthRegex,
|
||||||
|
skipAuthPreflight: opts.SkipAuthPreflight,
|
||||||
compiledRegex: opts.CompiledRegex,
|
compiledRegex: opts.CompiledRegex,
|
||||||
SetXAuthRequest: opts.SetXAuthRequest,
|
SetXAuthRequest: opts.SetXAuthRequest,
|
||||||
PassBasicAuth: opts.PassBasicAuth,
|
PassBasicAuth: opts.PassBasicAuth,
|
||||||
@ -421,6 +423,11 @@ func (p *OAuthProxy) GetRedirect(req *http.Request) (redirect string, err error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *OAuthProxy) IsWhitelistedRequest(req *http.Request) (ok bool) {
|
||||||
|
isPreflightRequestAllowed := p.skipAuthPreflight && req.Method == "OPTIONS"
|
||||||
|
return isPreflightRequestAllowed || p.IsWhitelistedPath(req.URL.Path)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *OAuthProxy) IsWhitelistedPath(path string) (ok bool) {
|
func (p *OAuthProxy) IsWhitelistedPath(path string) (ok bool) {
|
||||||
for _, u := range p.compiledRegex {
|
for _, u := range p.compiledRegex {
|
||||||
ok = u.MatchString(path)
|
ok = u.MatchString(path)
|
||||||
@ -445,7 +452,7 @@ func (p *OAuthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|||||||
p.RobotsTxt(rw)
|
p.RobotsTxt(rw)
|
||||||
case path == p.PingPath:
|
case path == p.PingPath:
|
||||||
p.PingPage(rw)
|
p.PingPage(rw)
|
||||||
case p.IsWhitelistedPath(path):
|
case p.IsWhitelistedRequest(req):
|
||||||
p.serveMux.ServeHTTP(rw, req)
|
p.serveMux.ServeHTTP(rw, req)
|
||||||
case path == p.SignInPath:
|
case path == p.SignInPath:
|
||||||
p.SignIn(rw, req)
|
p.SignIn(rw, req)
|
||||||
|
@ -641,6 +641,33 @@ func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
|
|||||||
assert.Equal(t, "oauth_user@example.com", pc_test.rw.HeaderMap["X-Auth-Request-Email"][0])
|
assert.Equal(t, "oauth_user@example.com", pc_test.rw.HeaderMap["X-Auth-Request-Email"][0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAuthSkippedForPreflightRequests(t *testing.T) {
|
||||||
|
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(200)
|
||||||
|
w.Write([]byte("response"))
|
||||||
|
}))
|
||||||
|
defer upstream.Close()
|
||||||
|
|
||||||
|
opts := NewOptions()
|
||||||
|
opts.Upstreams = append(opts.Upstreams, upstream.URL)
|
||||||
|
opts.ClientID = "bazquux"
|
||||||
|
opts.ClientSecret = "foobar"
|
||||||
|
opts.CookieSecret = "xyzzyplugh"
|
||||||
|
opts.SkipAuthPreflight = true
|
||||||
|
opts.Validate()
|
||||||
|
|
||||||
|
upstream_url, _ := url.Parse(upstream.URL)
|
||||||
|
opts.provider = NewTestProvider(upstream_url, "")
|
||||||
|
|
||||||
|
proxy := NewOAuthProxy(opts, func(string) bool { return false })
|
||||||
|
rw := httptest.NewRecorder()
|
||||||
|
req, _ := http.NewRequest("OPTIONS", "/preflight-request", nil)
|
||||||
|
proxy.ServeHTTP(rw, req)
|
||||||
|
|
||||||
|
assert.Equal(t, 200, rw.Code)
|
||||||
|
assert.Equal(t, "response", rw.Body.String())
|
||||||
|
}
|
||||||
|
|
||||||
type SignatureAuthenticator struct {
|
type SignatureAuthenticator struct {
|
||||||
auth hmacauth.HmacAuth
|
auth hmacauth.HmacAuth
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ type Options struct {
|
|||||||
PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"`
|
PassUserHeaders bool `flag:"pass-user-headers" cfg:"pass_user_headers"`
|
||||||
SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"`
|
SSLInsecureSkipVerify bool `flag:"ssl-insecure-skip-verify" cfg:"ssl_insecure_skip_verify"`
|
||||||
SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest"`
|
SetXAuthRequest bool `flag:"set-xauthrequest" cfg:"set_xauthrequest"`
|
||||||
|
SkipAuthPreflight bool `flag:"skip-auth-preflight" cfg:"skip_auth_preflight"`
|
||||||
|
|
||||||
// These options allow for other providers besides Google, with
|
// These options allow for other providers besides Google, with
|
||||||
// potential overrides.
|
// potential overrides.
|
||||||
@ -99,6 +100,7 @@ func NewOptions() *Options {
|
|||||||
CookieExpire: time.Duration(168) * time.Hour,
|
CookieExpire: time.Duration(168) * time.Hour,
|
||||||
CookieRefresh: time.Duration(0),
|
CookieRefresh: time.Duration(0),
|
||||||
SetXAuthRequest: false,
|
SetXAuthRequest: false,
|
||||||
|
SkipAuthPreflight: false,
|
||||||
PassBasicAuth: true,
|
PassBasicAuth: true,
|
||||||
PassUserHeaders: true,
|
PassUserHeaders: true,
|
||||||
PassAccessToken: false,
|
PassAccessToken: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user