Forward auth headers
This commit is contained in:
parent
df600d6f3c
commit
f9b1106df2
6 changed files with 40 additions and 13 deletions
|
@ -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{
|
forward = &types.Forward{
|
||||||
Address: address,
|
Address: address,
|
||||||
TLS: clientTLS,
|
TLS: clientTLS,
|
||||||
TrustForwardHeader: toBool(result, "auth_forward_trustforwardheader"),
|
TrustForwardHeader: toBool(result, "auth_forward_trustforwardheader"),
|
||||||
|
AuthResponseHeaders: authResponseHeaders,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ func Test_parseEntryPointsConfiguration(t *testing.T) {
|
||||||
"Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
|
"Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
|
||||||
"Auth.HeaderField:X-WebAuth-User " +
|
"Auth.HeaderField:X-WebAuth-User " +
|
||||||
"Auth.Forward.Address:https://authserver.com/auth " +
|
"Auth.Forward.Address:https://authserver.com/auth " +
|
||||||
|
"Auth.Forward.AuthResponseHeaders:X-Auth,X-Test,X-Secret " +
|
||||||
"Auth.Forward.TrustForwardHeader:true " +
|
"Auth.Forward.TrustForwardHeader:true " +
|
||||||
"Auth.Forward.TLS.CA:path/to/local.crt " +
|
"Auth.Forward.TLS.CA:path/to/local.crt " +
|
||||||
"Auth.Forward.TLS.CAOptional:true " +
|
"Auth.Forward.TLS.CAOptional:true " +
|
||||||
|
@ -50,6 +51,7 @@ func Test_parseEntryPointsConfiguration(t *testing.T) {
|
||||||
"auth_basic_users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
"auth_basic_users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||||
"auth_digest_users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e",
|
"auth_digest_users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e",
|
||||||
"auth_forward_address": "https://authserver.com/auth",
|
"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_ca": "path/to/local.crt",
|
||||||
"auth_forward_tls_caoptional": "true",
|
"auth_forward_tls_caoptional": "true",
|
||||||
"auth_forward_tls_cert": "path/to/foo.cert",
|
"auth_forward_tls_cert": "path/to/foo.cert",
|
||||||
|
@ -191,6 +193,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
"Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
|
"Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
|
||||||
"Auth.HeaderField:X-WebAuth-User " +
|
"Auth.HeaderField:X-WebAuth-User " +
|
||||||
"Auth.Forward.Address:https://authserver.com/auth " +
|
"Auth.Forward.Address:https://authserver.com/auth " +
|
||||||
|
"Auth.Forward.AuthResponseHeaders:X-Auth,X-Test,X-Secret " +
|
||||||
"Auth.Forward.TrustForwardHeader:true " +
|
"Auth.Forward.TrustForwardHeader:true " +
|
||||||
"Auth.Forward.TLS.CA:path/to/local.crt " +
|
"Auth.Forward.TLS.CA:path/to/local.crt " +
|
||||||
"Auth.Forward.TLS.CAOptional:true " +
|
"Auth.Forward.TLS.CAOptional:true " +
|
||||||
|
@ -242,6 +245,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
},
|
},
|
||||||
Forward: &types.Forward{
|
Forward: &types.Forward{
|
||||||
Address: "https://authserver.com/auth",
|
Address: "https://authserver.com/auth",
|
||||||
|
AuthResponseHeaders: []string{"X-Auth", "X-Test", "X-Secret"},
|
||||||
TLS: &types.ClientTLS{
|
TLS: &types.ClientTLS{
|
||||||
CA: "path/to/local.crt",
|
CA: "path/to/local.crt",
|
||||||
CAOptional: true,
|
CAOptional: true,
|
||||||
|
@ -302,6 +306,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
"auth.digest.users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
|
"auth.digest.users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e " +
|
||||||
"auth.headerField:X-WebAuth-User " +
|
"auth.headerField:X-WebAuth-User " +
|
||||||
"auth.forward.address:https://authserver.com/auth " +
|
"auth.forward.address:https://authserver.com/auth " +
|
||||||
|
"auth.forward.authResponseHeaders:X-Auth,X-Test,X-Secret " +
|
||||||
"auth.forward.trustForwardHeader:true " +
|
"auth.forward.trustForwardHeader:true " +
|
||||||
"auth.forward.tls.ca:path/to/local.crt " +
|
"auth.forward.tls.ca:path/to/local.crt " +
|
||||||
"auth.forward.tls.caOptional:true " +
|
"auth.forward.tls.caOptional:true " +
|
||||||
|
@ -350,6 +355,7 @@ func TestEntryPoints_Set(t *testing.T) {
|
||||||
},
|
},
|
||||||
Forward: &types.Forward{
|
Forward: &types.Forward{
|
||||||
Address: "https://authserver.com/auth",
|
Address: "https://authserver.com/auth",
|
||||||
|
AuthResponseHeaders: []string{"X-Auth", "X-Test", "X-Secret"},
|
||||||
TLS: &types.ClientTLS{
|
TLS: &types.ClientTLS{
|
||||||
CA: "path/to/local.crt",
|
CA: "path/to/local.crt",
|
||||||
CAOptional: true,
|
CAOptional: true,
|
||||||
|
|
|
@ -60,6 +60,8 @@
|
||||||
cert = "path/to/foo.cert"
|
cert = "path/to/foo.cert"
|
||||||
key = "path/to/foo.key"
|
key = "path/to/foo.key"
|
||||||
insecureSkipVerify = true
|
insecureSkipVerify = true
|
||||||
|
[entryPoints.http.auth.forward]
|
||||||
|
authResponseHeaders = ["X-Auth-User"]
|
||||||
|
|
||||||
[entryPoints.http.proxyProtocol]
|
[entryPoints.http.proxyProtocol]
|
||||||
insecure = true
|
insecure = true
|
||||||
|
@ -126,6 +128,7 @@ Auth.Basic.Users:test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB
|
||||||
Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e
|
Auth.Digest.Users:test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e
|
||||||
Auth.HeaderField:X-WebAuth-User
|
Auth.HeaderField:X-WebAuth-User
|
||||||
Auth.Forward.Address:https://authserver.com/auth
|
Auth.Forward.Address:https://authserver.com/auth
|
||||||
|
Auth.Forward.AuthResponseHeaders:X-Auth,X-Test,X-Secret
|
||||||
Auth.Forward.TrustForwardHeader:true
|
Auth.Forward.TrustForwardHeader:true
|
||||||
Auth.Forward.TLS.CA:path/to/local.crt
|
Auth.Forward.TLS.CA:path/to/local.crt
|
||||||
Auth.Forward.TLS.CAOptional:true
|
Auth.Forward.TLS.CAOptional:true
|
||||||
|
@ -310,6 +313,10 @@ Otherwise, the response from the authentication server is returned.
|
||||||
#
|
#
|
||||||
trustForwardHeader = true
|
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.
|
# Enable forward auth TLS connection.
|
||||||
#
|
#
|
||||||
# Optional
|
# Optional
|
||||||
|
|
|
@ -94,6 +94,10 @@ func Forward(config *types.Forward, w http.ResponseWriter, r *http.Request, next
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, headerName := range config.AuthResponseHeaders {
|
||||||
|
r.Header.Set(headerName, forwardResponse.Header.Get(headerName))
|
||||||
|
}
|
||||||
|
|
||||||
r.RequestURI = r.URL.RequestURI()
|
r.RequestURI = r.URL.RequestURI()
|
||||||
next(w, r)
|
next(w, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,8 @@ func TestForwardAuthFail(t *testing.T) {
|
||||||
ts := httptest.NewServer(n)
|
ts := httptest.NewServer(n)
|
||||||
defer ts.Close()
|
defer ts.Close()
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil)
|
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.NoError(t, err, "there should be no error")
|
||||||
assert.Equal(t, http.StatusForbidden, res.StatusCode, "they should be equal")
|
assert.Equal(t, http.StatusForbidden, res.StatusCode, "they should be equal")
|
||||||
|
|
||||||
|
@ -49,6 +48,8 @@ func TestForwardAuthFail(t *testing.T) {
|
||||||
|
|
||||||
func TestForwardAuthSuccess(t *testing.T) {
|
func TestForwardAuthSuccess(t *testing.T) {
|
||||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
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")
|
fmt.Fprintln(w, "Success")
|
||||||
}))
|
}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
@ -56,11 +57,14 @@ func TestForwardAuthSuccess(t *testing.T) {
|
||||||
middleware, err := NewAuthenticator(&types.Auth{
|
middleware, err := NewAuthenticator(&types.Auth{
|
||||||
Forward: &types.Forward{
|
Forward: &types.Forward{
|
||||||
Address: server.URL,
|
Address: server.URL,
|
||||||
|
AuthResponseHeaders: []string{"X-Auth-User"},
|
||||||
},
|
},
|
||||||
}, &tracing.Tracing{})
|
}, &tracing.Tracing{})
|
||||||
assert.NoError(t, err, "there should be no error")
|
assert.NoError(t, err, "there should be no error")
|
||||||
|
|
||||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
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")
|
fmt.Fprintln(w, "traefik")
|
||||||
})
|
})
|
||||||
n := negroni.New(middleware)
|
n := negroni.New(middleware)
|
||||||
|
@ -68,9 +72,8 @@ func TestForwardAuthSuccess(t *testing.T) {
|
||||||
ts := httptest.NewServer(n)
|
ts := httptest.NewServer(n)
|
||||||
defer ts.Close()
|
defer ts.Close()
|
||||||
|
|
||||||
client := &http.Client{}
|
|
||||||
req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil)
|
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.NoError(t, err, "there should be no error")
|
||||||
assert.Equal(t, http.StatusOK, res.StatusCode, "they should be equal")
|
assert.Equal(t, http.StatusOK, res.StatusCode, "they should be equal")
|
||||||
|
|
||||||
|
|
|
@ -415,6 +415,7 @@ type Forward struct {
|
||||||
Address string `description:"Authentication server address"`
|
Address string `description:"Authentication server address"`
|
||||||
TLS *ClientTLS `description:"Enable TLS support" export:"true"`
|
TLS *ClientTLS `description:"Enable TLS support" export:"true"`
|
||||||
TrustForwardHeader bool `description:"Trust X-Forwarded-* headers" 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
|
// CanonicalDomain returns a lower case domain with trim space
|
||||||
|
|
Loading…
Reference in a new issue