#369: Optionally allow skipping authentication for preflight requests

This commit is contained in:
idntfy 2017-04-07 14:55:48 +03:00 committed by Sergey Akimov
parent af7be2d622
commit 1e7d2a08a3
5 changed files with 39 additions and 1 deletions

View File

@ -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

View File

@ -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")

View File

@ -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)

View File

@ -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
} }

View File

@ -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,