Skip to content
This repository has been archived by the owner on Jan 24, 2019. It is now read-only.

various fixes for getting Nginx auth_request mode working #319

Merged
merged 3 commits into from Mar 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,10 +359,25 @@ server {
}

location /oauth2/ {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
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 / {
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func main() {
flagSet.String("tls-cert", "", "path to certificate 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.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.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")
Expand Down
11 changes: 11 additions & 0 deletions oauthproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type OAuthProxy struct {
HtpasswdFile *HtpasswdFile
DisplayHtpasswdForm bool
serveMux http.Handler
SetXAuthRequest bool
PassBasicAuth bool
SkipProviderButton bool
PassUserHeaders bool
Expand Down Expand Up @@ -198,6 +199,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
redirectURL: redirectURL,
skipAuthRegex: opts.SkipAuthRegex,
compiledRegex: opts.CompiledRegex,
SetXAuthRequest: opts.SetXAuthRequest,
PassBasicAuth: opts.PassBasicAuth,
PassUserHeaders: opts.PassUserHeaders,
BasicAuthPassword: opts.BasicAuthPassword,
Expand Down Expand Up @@ -361,6 +363,9 @@ func (p *OAuthProxy) SignInPage(rw http.ResponseWriter, req *http.Request, code
rw.WriteHeader(code)

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 {
redirect_url = "/"
}
Expand Down Expand Up @@ -663,6 +668,12 @@ func (p *OAuthProxy) Authenticate(rw http.ResponseWriter, req *http.Request) int
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 != "" {
req.Header["X-Forwarded-Access-Token"] = []string{session.AccessToken}
}
Expand Down
30 changes: 30 additions & 0 deletions oauthproxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,36 @@ func TestAuthOnlyEndpointUnauthorizedOnEmailValidationFailure(t *testing.T) {
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: "[email protected]", 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, "[email protected]", pc_test.rw.HeaderMap["X-Auth-Request-Email"][0])
}

type SignatureAuthenticator struct {
auth hmacauth.HmacAuth
}
Expand Down
2 changes: 2 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type Options struct {
SkipProviderButton bool `flag:"skip-provider-button" cfg:"skip_provider_button"`
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"`

// These options allow for other providers besides Google, with
// potential overrides.
Expand Down Expand Up @@ -97,6 +98,7 @@ func NewOptions() *Options {
CookieHttpOnly: true,
CookieExpire: time.Duration(168) * time.Hour,
CookieRefresh: time.Duration(0),
SetXAuthRequest: false,
PassBasicAuth: true,
PassUserHeaders: true,
PassAccessToken: false,
Expand Down