mirror of
https://github.com/containous/traefik.git
synced 2025-03-09 08:58:23 +03:00
Middlewares: add forwardAuth.authResponseHeadersRegex
This commit is contained in:
parent
b5198e63c4
commit
49cdb67ddc
@ -164,7 +164,7 @@ http:
|
||||
|
||||
### `authResponseHeaders`
|
||||
|
||||
The `authResponseHeaders` option is the list of the headers to copy from the authentication server to the request.
|
||||
The `authResponseHeaders` option is the list of the headers to copy from the authentication server to the request. All incoming request's headers in this list are deleted from the request before any copy happens.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
@ -217,6 +217,59 @@ http:
|
||||
- "X-Secret"
|
||||
```
|
||||
|
||||
### `authResponseHeadersRegex`
|
||||
|
||||
The `authResponseHeadersRegex` option is the regex to match the headers that should be copied from the authentication server to the request. All incoming request's headers matching this regex are deleted from the request before any copy happens.
|
||||
It allows partial matching of the regular expression against the header's key.
|
||||
You should use start of string (`^`) and end of string (`$`) anchors to ensure a full match against the header's key.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-auth
|
||||
spec:
|
||||
forwardAuth:
|
||||
address: https://example.com/auth
|
||||
authResponseHeadersRegex: ^X-
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex": "^X-"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-auth.forwardAuth]
|
||||
address = "https://example.com/auth"
|
||||
authResponseHeadersRegex = "^X-"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-auth:
|
||||
forwardAuth:
|
||||
address: "https://example.com/auth"
|
||||
authResponseHeadersRegex: "^X-"
|
||||
```
|
||||
|
||||
### `authRequestHeaders`
|
||||
|
||||
The `authRequestHeaders` option is the list of the headers to copy from the request to the authentication server.
|
||||
|
@ -24,6 +24,7 @@
|
||||
- "traefik.http.middlewares.middleware08.errors.status=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.address=foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.authresponseheaders=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.authresponseheadersregex=foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.authrequestheaders=foobar, foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.tls.ca=foobar"
|
||||
- "traefik.http.middlewares.middleware09.forwardauth.tls.caoptional=true"
|
||||
|
@ -139,6 +139,7 @@
|
||||
address = "foobar"
|
||||
trustForwardHeader = true
|
||||
authResponseHeaders = ["foobar", "foobar"]
|
||||
authResponseHeadersRegex = "foobar"
|
||||
authRequestHeaders = ["foobar", "foobar"]
|
||||
[http.middlewares.Middleware09.forwardAuth.tls]
|
||||
ca = "foobar"
|
||||
|
@ -158,6 +158,7 @@ http:
|
||||
authResponseHeaders:
|
||||
- foobar
|
||||
- foobar
|
||||
authResponseHeadersRegex: foobar
|
||||
authRequestHeaders:
|
||||
- foobar
|
||||
- foobar
|
||||
|
@ -31,6 +31,7 @@
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authRequestHeaders/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authResponseHeaders/0` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authResponseHeaders/1` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/authResponseHeadersRegex` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/tls/ca` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/tls/caOptional` | `true` |
|
||||
| `traefik/http/middlewares/Middleware09/forwardAuth/tls/cert` | `foobar` |
|
||||
|
@ -24,6 +24,7 @@
|
||||
"traefik.http.middlewares.middleware08.errors.status": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.address": "foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.authresponseheaders": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.authresponseheadersregex": "foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.authrequestheaders": "foobar, foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.tls.ca": "foobar",
|
||||
"traefik.http.middlewares.middleware09.forwardauth.tls.caoptional": "true",
|
||||
|
@ -288,6 +288,7 @@
|
||||
address = "foobar"
|
||||
trustForwardHeader = true
|
||||
authResponseHeaders = ["foobar", "foobar"]
|
||||
authResponseHeadersRegex = "foobar"
|
||||
authRequestHeaders = ["foobar", "foobar"]
|
||||
[http.middlewares.Middleware15.forwardAuth.tls]
|
||||
ca = "foobar"
|
||||
|
@ -144,6 +144,7 @@ type ForwardAuth struct {
|
||||
TLS *ClientTLS `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty"`
|
||||
TrustForwardHeader bool `json:"trustForwardHeader,omitempty" toml:"trustForwardHeader,omitempty" yaml:"trustForwardHeader,omitempty" export:"true"`
|
||||
AuthResponseHeaders []string `json:"authResponseHeaders,omitempty" toml:"authResponseHeaders,omitempty" yaml:"authResponseHeaders,omitempty"`
|
||||
AuthResponseHeadersRegex string `json:"authResponseHeadersRegex,omitempty" toml:"authResponseHeadersRegex,omitempty" yaml:"authResponseHeadersRegex,omitempty"`
|
||||
AuthRequestHeaders []string `json:"authRequestHeaders,omitempty" toml:"authRequestHeaders,omitempty" yaml:"authRequestHeaders,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -27,6 +28,7 @@ const (
|
||||
type forwardAuth struct {
|
||||
address string
|
||||
authResponseHeaders []string
|
||||
authResponseHeadersRegex *regexp.Regexp
|
||||
next http.Handler
|
||||
name string
|
||||
client http.Client
|
||||
@ -66,6 +68,14 @@ func NewForward(ctx context.Context, next http.Handler, config dynamic.ForwardAu
|
||||
fa.client.Transport = tr
|
||||
}
|
||||
|
||||
if config.AuthResponseHeadersRegex != "" {
|
||||
re, err := regexp.Compile(config.AuthResponseHeadersRegex)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error compiling regular expression %s: %w", config.AuthResponseHeadersRegex, err)
|
||||
}
|
||||
fa.authResponseHeadersRegex = re
|
||||
}
|
||||
|
||||
return fa, nil
|
||||
}
|
||||
|
||||
@ -156,6 +166,20 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if fa.authResponseHeadersRegex != nil {
|
||||
for headerKey := range req.Header {
|
||||
if fa.authResponseHeadersRegex.MatchString(headerKey) {
|
||||
req.Header.Del(headerKey)
|
||||
}
|
||||
}
|
||||
|
||||
for headerKey, headerValues := range forwardResponse.Header {
|
||||
if fa.authResponseHeadersRegex.MatchString(headerKey) {
|
||||
req.Header[headerKey] = append([]string(nil), headerValues...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
req.RequestURI = req.URL.RequestURI()
|
||||
fa.next.ServeHTTP(rw, req)
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ func TestForwardAuthSuccess(t *testing.T) {
|
||||
w.Header().Set("X-Auth-Secret", "secret")
|
||||
w.Header().Add("X-Auth-Group", "group1")
|
||||
w.Header().Add("X-Auth-Group", "group2")
|
||||
w.Header().Add("Foo-Bar", "auth-value")
|
||||
fmt.Fprintln(w, "Success")
|
||||
}))
|
||||
t.Cleanup(server.Close)
|
||||
@ -65,12 +66,15 @@ func TestForwardAuthSuccess(t *testing.T) {
|
||||
assert.Equal(t, "user@example.com", r.Header.Get("X-Auth-User"))
|
||||
assert.Empty(t, r.Header.Get("X-Auth-Secret"))
|
||||
assert.Equal(t, []string{"group1", "group2"}, r.Header["X-Auth-Group"])
|
||||
assert.Equal(t, "auth-value", r.Header.Get("Foo-Bar"))
|
||||
assert.Empty(t, r.Header.Get("Foo-Baz"))
|
||||
fmt.Fprintln(w, "traefik")
|
||||
})
|
||||
|
||||
auth := dynamic.ForwardAuth{
|
||||
Address: server.URL,
|
||||
AuthResponseHeaders: []string{"X-Auth-User", "X-Auth-Group"},
|
||||
AuthResponseHeadersRegex: "^Foo-",
|
||||
}
|
||||
middleware, err := NewForward(context.Background(), next, auth, "authTest")
|
||||
require.NoError(t, err)
|
||||
@ -80,6 +84,8 @@ func TestForwardAuthSuccess(t *testing.T) {
|
||||
|
||||
req := testhelpers.MustNewRequest(http.MethodGet, ts.URL, nil)
|
||||
req.Header.Set("X-Auth-Group", "admin_group")
|
||||
req.Header.Set("Foo-Bar", "client-value")
|
||||
req.Header.Set("Foo-Baz", "client-value")
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||
|
@ -376,6 +376,7 @@ func createForwardAuthMiddleware(k8sClient Client, namespace string, auth *v1alp
|
||||
Address: auth.Address,
|
||||
TrustForwardHeader: auth.TrustForwardHeader,
|
||||
AuthResponseHeaders: auth.AuthResponseHeaders,
|
||||
AuthResponseHeadersRegex: auth.AuthResponseHeadersRegex,
|
||||
AuthRequestHeaders: auth.AuthRequestHeaders,
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,7 @@ type ForwardAuth struct {
|
||||
Address string `json:"address,omitempty"`
|
||||
TrustForwardHeader bool `json:"trustForwardHeader,omitempty"`
|
||||
AuthResponseHeaders []string `json:"authResponseHeaders,omitempty"`
|
||||
AuthResponseHeadersRegex string `json:"authResponseHeadersRegex,omitempty"`
|
||||
AuthRequestHeaders []string `json:"authRequestHeaders,omitempty"`
|
||||
TLS *ClientTLS `json:"tls,omitempty"`
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user