Merge pull request #319 from advarisk/auth-request
various fixes for getting Nginx auth_request mode working
This commit is contained in:
commit
af7be2d622
23
README.md
23
README.md
@ -359,10 +359,25 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
location /oauth2/ {
|
location /oauth2/ {
|
||||||
proxy_pass http://127.0.0.1:4180;
|
proxy_pass http://127.0.0.1:4180;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Scheme $scheme;
|
proxy_set_header X-Scheme $scheme;
|
||||||
|
proxy_set_header X-Auth-Request-Redirect $request_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /upstream/ {
|
||||||
|
auth_request /oauth2/auth;
|
||||||
|
error_page 401 = /oauth2/sign_in;
|
||||||
|
|
||||||
|
# pass information via X-User and X-Email headers to backend,
|
||||||
|
# requires running with --set-xauthrequest flag
|
||||||
|
auth_request_set $user $upstream_http_x_auth_request_user;
|
||||||
|
auth_request_set $email $upstream_http_x_auth_request_email;
|
||||||
|
proxy_set_header X-User $user;
|
||||||
|
proxy_set_header X-Email $email;
|
||||||
|
|
||||||
|
proxy_pass http://backend/;
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
1
main.go
1
main.go
@ -30,6 +30,7 @@ func main() {
|
|||||||
flagSet.String("tls-cert", "", "path to certificate file")
|
flagSet.String("tls-cert", "", "path to certificate file")
|
||||||
flagSet.String("tls-key", "", "path to private key file")
|
flagSet.String("tls-key", "", "path to private key file")
|
||||||
flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
|
flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
|
||||||
|
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 or file:// paths for static files. Routing is based on the path")
|
flagSet.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint or file:// paths for static files. 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("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")
|
||||||
|
@ -60,6 +60,7 @@ type OAuthProxy struct {
|
|||||||
HtpasswdFile *HtpasswdFile
|
HtpasswdFile *HtpasswdFile
|
||||||
DisplayHtpasswdForm bool
|
DisplayHtpasswdForm bool
|
||||||
serveMux http.Handler
|
serveMux http.Handler
|
||||||
|
SetXAuthRequest bool
|
||||||
PassBasicAuth bool
|
PassBasicAuth bool
|
||||||
SkipProviderButton bool
|
SkipProviderButton bool
|
||||||
PassUserHeaders bool
|
PassUserHeaders bool
|
||||||
@ -198,6 +199,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
|
|||||||
redirectURL: redirectURL,
|
redirectURL: redirectURL,
|
||||||
skipAuthRegex: opts.SkipAuthRegex,
|
skipAuthRegex: opts.SkipAuthRegex,
|
||||||
compiledRegex: opts.CompiledRegex,
|
compiledRegex: opts.CompiledRegex,
|
||||||
|
SetXAuthRequest: opts.SetXAuthRequest,
|
||||||
PassBasicAuth: opts.PassBasicAuth,
|
PassBasicAuth: opts.PassBasicAuth,
|
||||||
PassUserHeaders: opts.PassUserHeaders,
|
PassUserHeaders: opts.PassUserHeaders,
|
||||||
BasicAuthPassword: opts.BasicAuthPassword,
|
BasicAuthPassword: opts.BasicAuthPassword,
|
||||||
@ -361,6 +363,9 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
|
|||||||
rw.WriteHeader(code)
|
rw.WriteHeader(code)
|
||||||
|
|
||||||
redirect_url := req.URL.RequestURI()
|
redirect_url := req.URL.RequestURI()
|
||||||
|
if req.Header.Get("X-Auth-Request-Redirect") != "" {
|
||||||
|
redirect_url = req.Header.Get("X-Auth-Request-Redirect")
|
||||||
|
}
|
||||||
if redirect_url == p.SignInPath {
|
if redirect_url == p.SignInPath {
|
||||||
redirect_url = "/"
|
redirect_url = "/"
|
||||||
}
|
}
|
||||||
@ -663,6 +668,12 @@ func (p *OAuthProxy) Authenticate(rw http.ResponseWriter, req *http.Request) int
|
|||||||
req.Header["X-Forwarded-Email"] = []string{session.Email}
|
req.Header["X-Forwarded-Email"] = []string{session.Email}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if p.SetXAuthRequest {
|
||||||
|
rw.Header().Set("X-Auth-Request-User", session.User)
|
||||||
|
if session.Email != "" {
|
||||||
|
rw.Header().Set("X-Auth-Request-Email", session.Email)
|
||||||
|
}
|
||||||
|
}
|
||||||
if p.PassAccessToken && session.AccessToken != "" {
|
if p.PassAccessToken && session.AccessToken != "" {
|
||||||
req.Header["X-Forwarded-Access-Token"] = []string{session.AccessToken}
|
req.Header["X-Forwarded-Access-Token"] = []string{session.AccessToken}
|
||||||
}
|
}
|
||||||
|
@ -611,6 +611,36 @@ func TestAuthOnlyEndpointUnauthorizedOnEmailValidationFailure(t *testing.T) {
|
|||||||
assert.Equal(t, "unauthorized request\n", string(bodyBytes))
|
assert.Equal(t, "unauthorized request\n", string(bodyBytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAuthOnlyEndpointSetXAuthRequestHeaders(t *testing.T) {
|
||||||
|
var pc_test ProcessCookieTest
|
||||||
|
|
||||||
|
pc_test.opts = NewOptions()
|
||||||
|
pc_test.opts.SetXAuthRequest = true
|
||||||
|
pc_test.opts.Validate()
|
||||||
|
|
||||||
|
pc_test.proxy = NewOAuthProxy(pc_test.opts, func(email string) bool {
|
||||||
|
return pc_test.validate_user
|
||||||
|
})
|
||||||
|
pc_test.proxy.provider = &TestProvider{
|
||||||
|
ValidToken: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
pc_test.validate_user = true
|
||||||
|
|
||||||
|
pc_test.rw = httptest.NewRecorder()
|
||||||
|
pc_test.req, _ = http.NewRequest("GET",
|
||||||
|
pc_test.opts.ProxyPrefix+"/auth", nil)
|
||||||
|
|
||||||
|
startSession := &providers.SessionState{
|
||||||
|
User: "oauth_user", Email: "oauth_user@example.com", AccessToken: "oauth_token"}
|
||||||
|
pc_test.SaveSession(startSession, time.Now())
|
||||||
|
|
||||||
|
pc_test.proxy.ServeHTTP(pc_test.rw, pc_test.req)
|
||||||
|
assert.Equal(t, http.StatusAccepted, pc_test.rw.Code)
|
||||||
|
assert.Equal(t, "oauth_user", pc_test.rw.HeaderMap["X-Auth-Request-User"][0])
|
||||||
|
assert.Equal(t, "oauth_user@example.com", pc_test.rw.HeaderMap["X-Auth-Request-Email"][0])
|
||||||
|
}
|
||||||
|
|
||||||
type SignatureAuthenticator struct {
|
type SignatureAuthenticator struct {
|
||||||
auth hmacauth.HmacAuth
|
auth hmacauth.HmacAuth
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,7 @@ type Options struct {
|
|||||||
SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button"`
|
SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button"`
|
||||||
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"`
|
||||||
|
|
||||||
// These options allow for other providers besides Google, with
|
// These options allow for other providers besides Google, with
|
||||||
// potential overrides.
|
// potential overrides.
|
||||||
@ -97,6 +98,7 @@ func NewOptions() *Options {
|
|||||||
CookieHttpOnly: true,
|
CookieHttpOnly: true,
|
||||||
CookieExpire: time.Duration(168) * time.Hour,
|
CookieExpire: time.Duration(168) * time.Hour,
|
||||||
CookieRefresh: time.Duration(0),
|
CookieRefresh: time.Duration(0),
|
||||||
|
SetXAuthRequest: false,
|
||||||
PassBasicAuth: true,
|
PassBasicAuth: true,
|
||||||
PassUserHeaders: true,
|
PassUserHeaders: true,
|
||||||
PassAccessToken: false,
|
PassAccessToken: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user