Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forward auth headers #3521

Merged
merged 4 commits into from
Jun 30, 2018
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
12 changes: 9 additions & 3 deletions configuration/entrypoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,16 @@ func makeEntryPointAuth(result map[string]string) *types.Auth {
}
}

var authResponseHeaders []string
if v, ok := result["auth_forward_authresponseheaders"]; ok {
authResponseHeaders = strings.Split(v, ",")
}

forward = &types.Forward{
Address: address,
TLS: clientTLS,
TrustForwardHeader: toBool(result, "auth_forward_trustforwardheader"),
Address: address,
TLS: clientTLS,
TrustForwardHeader: toBool(result, "auth_forward_trustforwardheader"),
AuthResponseHeaders: authResponseHeaders,
}
}

Expand Down
10 changes: 8 additions & 2 deletions configuration/entrypoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func Test_parseEntryPointsConfiguration(t *testing.T) {
"Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
"Auth.HeaderField:X-WebAuth-User " +
"Auth.Forward.Address:https://authserver.com/auth " +
"Auth.Forward.AuthResponseHeaders:X-Auth,X-Test,X-Secret " +
"Auth.Forward.TrustForwardHeader:true " +
"Auth.Forward.TLS.CA:path/to/local.crt " +
"Auth.Forward.TLS.CAOptional:true " +
Expand All @@ -50,6 +51,7 @@ func Test_parseEntryPointsConfiguration(t *testing.T) {
"auth_basic_users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
"auth_digest_users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e",
"auth_forward_address": "https://authserver.com/auth",
"auth_forward_authresponseheaders": "X-Auth,X-Test,X-Secret",
"auth_forward_tls_ca": "path/to/local.crt",
"auth_forward_tls_caoptional": "true",
"auth_forward_tls_cert": "path/to/foo.cert",
Expand Down Expand Up @@ -191,6 +193,7 @@ func TestEntryPoints_Set(t *testing.T) {
"Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
"Auth.HeaderField:X-WebAuth-User " +
"Auth.Forward.Address:https://authserver.com/auth " +
"Auth.Forward.AuthResponseHeaders:X-Auth,X-Test,X-Secret " +
"Auth.Forward.TrustForwardHeader:true " +
"Auth.Forward.TLS.CA:path/to/local.crt " +
"Auth.Forward.TLS.CAOptional:true " +
Expand Down Expand Up @@ -241,7 +244,8 @@ func TestEntryPoints_Set(t *testing.T) {
},
},
Forward: &types.Forward{
Address: "https://authserver.com/auth",
Address: "https://authserver.com/auth",
AuthResponseHeaders: []string{"X-Auth", "X-Test", "X-Secret"},
TLS: &types.ClientTLS{
CA: "path/to/local.crt",
CAOptional: true,
Expand Down Expand Up @@ -302,6 +306,7 @@ func TestEntryPoints_Set(t *testing.T) {
"auth.digest.users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
"auth.headerField:X-WebAuth-User " +
"auth.forward.address:https://authserver.com/auth " +
"auth.forward.authResponseHeaders:X-Auth,X-Test,X-Secret " +
"auth.forward.trustForwardHeader:true " +
"auth.forward.tls.ca:path/to/local.crt " +
"auth.forward.tls.caOptional:true " +
Expand Down Expand Up @@ -349,7 +354,8 @@ func TestEntryPoints_Set(t *testing.T) {
},
},
Forward: &types.Forward{
Address: "https://authserver.com/auth",
Address: "https://authserver.com/auth",
AuthResponseHeaders: []string{"X-Auth", "X-Test", "X-Secret"},
TLS: &types.ClientTLS{
CA: "path/to/local.crt",
CAOptional: true,
Expand Down
7 changes: 7 additions & 0 deletions docs/configuration/entrypoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
cert = "path/to/foo.cert"
key = "path/to/foo.key"
insecureSkipVerify = true
[entryPoints.http.auth.forward]
authResponseHeaders = ["X-Auth-User"]

[entryPoints.http.proxyProtocol]
insecure = true
Expand Down Expand Up @@ -126,6 +128,7 @@ Auth.Basic.Users:test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB
Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e
Auth.HeaderField:X-WebAuth-User
Auth.Forward.Address:https://authserver.com/auth
Auth.Forward.AuthResponseHeaders:X-Auth,X-Test,X-Secret
Auth.Forward.TrustForwardHeader:true
Auth.Forward.TLS.CA:path/to/local.crt
Auth.Forward.TLS.CAOptional:true
Expand Down Expand Up @@ -310,6 +313,10 @@ Otherwise, the response from the authentication server is returned.
#
trustForwardHeader = true

# Copy headers from the authentication server to the request
[entryPoints.http.auth.forward]
authResponseHeaders = ["X-Auth-User", "X-Secret"]

# Enable forward auth TLS connection.
#
# Optional
Expand Down
4 changes: 4 additions & 0 deletions middlewares/auth/forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func Forward(config *types.Forward, w http.ResponseWriter, r *http.Request, next
return
}

for _, headerName := range config.AuthResponseHeaders {
r.Header.Set(headerName, forwardResponse.Header.Get(headerName))
}

r.RequestURI = r.URL.RequestURI()
next(w, r)
}
Expand Down
13 changes: 8 additions & 5 deletions middlewares/auth/forward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ func TestForwardAuthFail(t *testing.T) {
ts := httptest.NewServer(n)
defer ts.Close()

client := &http.Client{}
req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil)
res, err := client.Do(req)
res, err := http.DefaultClient.Do(req)
assert.NoError(t, err, "there should be no error")
assert.Equal(t, http.StatusForbidden, res.StatusCode, "they should be equal")

Expand All @@ -49,28 +48,32 @@ func TestForwardAuthFail(t *testing.T) {

func TestForwardAuthSuccess(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Auth-User", "user@example.com")
w.Header().Set("X-Auth-Secret", "secret")
fmt.Fprintln(w, "Success")
}))
defer server.Close()

middleware, err := NewAuthenticator(&types.Auth{
Forward: &types.Forward{
Address: server.URL,
Address: server.URL,
AuthResponseHeaders: []string{"X-Auth-User"},
},
}, &tracing.Tracing{})
assert.NoError(t, err, "there should be no error")

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "user@example.com", r.Header.Get("X-Auth-User"))
assert.Empty(t, r.Header.Get("X-Auth-Secret"))
fmt.Fprintln(w, "traefik")
})
n := negroni.New(middleware)
n.UseHandler(handler)
ts := httptest.NewServer(n)
defer ts.Close()

client := &http.Client{}
req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil)
res, err := client.Do(req)
res, err := http.DefaultClient.Do(req)
assert.NoError(t, err, "there should be no error")
assert.Equal(t, http.StatusOK, res.StatusCode, "they should be equal")

Expand Down
7 changes: 4 additions & 3 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,9 +412,10 @@ type Digest struct {

// Forward authentication
type Forward struct {
Address string `description:"Authentication server address"`
TLS *ClientTLS `description:"Enable TLS support" export:"true"`
TrustForwardHeader bool `description:"Trust X-Forwarded-* headers" export:"true"`
Address string `description:"Authentication server address"`
TLS *ClientTLS `description:"Enable TLS support" export:"true"`
TrustForwardHeader bool `description:"Trust X-Forwarded-* headers" export:"true"`
AuthResponseHeaders []string `description:"Headers to be forwarded from auth response"`
}

// CanonicalDomain returns a lower case domain with trim space
Expand Down