feat: always set auth cookie (#8213)
* feat: always set auth cookie Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * feat: Add annotation to always set auth cookie * Add annotation * Add global configmap key * Provide unit tests and e2e tests * Fix e2e documentation autogen script Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com> * Regenerate e2e tests Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com>
This commit is contained in:
parent
93af9f726a
commit
2c27e66cc7
13 changed files with 501 additions and 537 deletions
|
|
@ -48,6 +48,7 @@ type Config struct {
|
|||
KeepaliveRequests int `json:"keepaliveRequests"`
|
||||
KeepaliveTimeout int `json:"keepaliveTimeout"`
|
||||
ProxySetHeaders map[string]string `json:"proxySetHeaders,omitempty"`
|
||||
AlwaysSetCookie bool `json:"alwaysSetCookie,omitempty"`
|
||||
}
|
||||
|
||||
// DefaultCacheDuration is the fallback value if no cache duration is provided
|
||||
|
|
@ -112,6 +113,10 @@ func (e1 *Config) Equal(e2 *Config) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
if e1.AlwaysSetCookie != e2.AlwaysSetCookie {
|
||||
return false
|
||||
}
|
||||
|
||||
return sets.StringElementsMatch(e1.AuthCacheDuration, e2.AuthCacheDuration)
|
||||
}
|
||||
|
||||
|
|
@ -297,6 +302,8 @@ func (a authReq) Parse(ing *networking.Ingress) (interface{}, error) {
|
|||
|
||||
requestRedirect, _ := parser.GetStringAnnotation("auth-request-redirect", ing)
|
||||
|
||||
alwaysSetCookie, _ := parser.GetBoolAnnotation("auth-always-set-cookie", ing)
|
||||
|
||||
return &Config{
|
||||
URL: urlString,
|
||||
Host: authURL.Hostname(),
|
||||
|
|
@ -312,6 +319,7 @@ func (a authReq) Parse(ing *networking.Ingress) (interface{}, error) {
|
|||
KeepaliveRequests: keepaliveRequests,
|
||||
KeepaliveTimeout: keepaliveTimeout,
|
||||
ProxySetHeaders: proxySetHeaders,
|
||||
AlwaysSetCookie: alwaysSetCookie,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,13 @@ func buildIngress() *networking.Ingress {
|
|||
}
|
||||
}
|
||||
|
||||
func boolToString(v bool) string {
|
||||
if v {
|
||||
return "true"
|
||||
}
|
||||
return "false"
|
||||
}
|
||||
|
||||
func TestAnnotations(t *testing.T) {
|
||||
ing := buildIngress()
|
||||
|
||||
|
|
@ -86,19 +93,20 @@ func TestAnnotations(t *testing.T) {
|
|||
requestRedirect string
|
||||
authSnippet string
|
||||
authCacheKey string
|
||||
authAlwaysSetCookie bool
|
||||
expErr bool
|
||||
}{
|
||||
{"empty", "", "", "", "", "", "", "", true},
|
||||
{"no scheme", "bar", "bar", "", "", "", "", "", true},
|
||||
{"invalid host", "http://", "http://", "", "", "", "", "", true},
|
||||
{"invalid host (multiple dots)", "http://foo..bar.com", "http://foo..bar.com", "", "", "", "", "", true},
|
||||
{"valid URL", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "", "", "", "", "", false},
|
||||
{"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "POST", "", "", "", false},
|
||||
{"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "", "", "", false},
|
||||
{"valid URL - request redirect", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "http://foo.com/redirect-me", "", "", false},
|
||||
{"auth snippet", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "proxy_set_header My-Custom-Header 42;", "", false},
|
||||
{"auth cache ", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "", "$foo$bar", false},
|
||||
{"redirect param", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "origUrl", "", "", "", "", false},
|
||||
{"empty", "", "", "", "", "", "", "", false, true},
|
||||
{"no scheme", "bar", "bar", "", "", "", "", "", false, true},
|
||||
{"invalid host", "http://", "http://", "", "", "", "", "", false, true},
|
||||
{"invalid host (multiple dots)", "http://foo..bar.com", "http://foo..bar.com", "", "", "", "", "", false, true},
|
||||
{"valid URL", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "", "", "", "", "", false, false},
|
||||
{"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "POST", "", "", "", false, false},
|
||||
{"valid URL - send body", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "", "", "", false, false},
|
||||
{"valid URL - request redirect", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "GET", "http://foo.com/redirect-me", "", "", false, false},
|
||||
{"auth snippet", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "proxy_set_header My-Custom-Header 42;", "", false, false},
|
||||
{"auth cache ", "http://foo.com/external-auth", "http://foo.com/external-auth", "", "", "", "", "$foo$bar", false, false},
|
||||
{"redirect param", "http://bar.foo.com/external-auth", "http://bar.foo.com/external-auth", "origUrl", "", "", "", "", true, false},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
@ -109,6 +117,7 @@ func TestAnnotations(t *testing.T) {
|
|||
data[parser.GetAnnotationWithPrefix("auth-request-redirect")] = test.requestRedirect
|
||||
data[parser.GetAnnotationWithPrefix("auth-snippet")] = test.authSnippet
|
||||
data[parser.GetAnnotationWithPrefix("auth-cache-key")] = test.authCacheKey
|
||||
data[parser.GetAnnotationWithPrefix("auth-always-set-cookie")] = boolToString(test.authAlwaysSetCookie)
|
||||
|
||||
i, err := NewParser(&resolver.Mock{}).Parse(ing)
|
||||
if test.expErr {
|
||||
|
|
@ -146,6 +155,10 @@ func TestAnnotations(t *testing.T) {
|
|||
if u.AuthCacheKey != test.authCacheKey {
|
||||
t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.authCacheKey, u.AuthCacheKey)
|
||||
}
|
||||
|
||||
if u.AlwaysSetCookie != test.authAlwaysSetCookie {
|
||||
t.Errorf("%v: expected \"%v\" but \"%v\" was returned", test.title, test.authAlwaysSetCookie, u.AlwaysSetCookie)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ func NewDefault() Configuration {
|
|||
defNginxStatusIpv4Whitelist = append(defNginxStatusIpv4Whitelist, "127.0.0.1")
|
||||
defNginxStatusIpv6Whitelist = append(defNginxStatusIpv6Whitelist, "::1")
|
||||
defProxyDeadlineDuration := time.Duration(5) * time.Second
|
||||
defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}}
|
||||
defGlobalExternalAuth := GlobalExternalAuth{"", "", "", "", "", append(defResponseHeaders, ""), "", "", "", []string{}, map[string]string{}, false}
|
||||
|
||||
cfg := Configuration{
|
||||
|
||||
|
|
@ -995,4 +995,5 @@ type GlobalExternalAuth struct {
|
|||
AuthCacheKey string `json:"authCacheKey"`
|
||||
AuthCacheDuration []string `json:"authCacheDuration"`
|
||||
ProxySetHeaders map[string]string `json:"proxySetHeaders,omitempty"`
|
||||
AlwaysSetCookie bool `json:"alwaysSetCookie,omitempty"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ const (
|
|||
globalAuthSnippet = "global-auth-snippet"
|
||||
globalAuthCacheKey = "global-auth-cache-key"
|
||||
globalAuthCacheDuration = "global-auth-cache-duration"
|
||||
globalAuthAlwaysSetCookie = "global-auth-always-set-cookie"
|
||||
luaSharedDictsKey = "lua-shared-dicts"
|
||||
plugins = "plugins"
|
||||
)
|
||||
|
|
@ -315,6 +316,16 @@ func ReadConfig(src map[string]string) config.Configuration {
|
|||
to.GlobalExternalAuth.AuthCacheDuration = cacheDurations
|
||||
}
|
||||
|
||||
if val, ok := conf[globalAuthAlwaysSetCookie]; ok {
|
||||
delete(conf, globalAuthAlwaysSetCookie)
|
||||
|
||||
alwaysSetCookie, err := strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
klog.Warningf("Global auth location denied - %s", fmt.Errorf("cannot convert %s to bool: %v", globalAuthAlwaysSetCookie, err))
|
||||
}
|
||||
to.GlobalExternalAuth.AlwaysSetCookie = alwaysSetCookie
|
||||
}
|
||||
|
||||
// Verify that the configured timeout is parsable as a duration. if not, set the default value
|
||||
if val, ok := conf[proxyHeaderTimeout]; ok {
|
||||
delete(conf, proxyHeaderTimeout)
|
||||
|
|
|
|||
|
|
@ -229,6 +229,34 @@ func TestGlobalExternalAuthSigninParsing(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGlobalExternalAlwaysSetCookie(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
alwaysSetCookie string
|
||||
result bool
|
||||
}{
|
||||
"true": {
|
||||
alwaysSetCookie: "true",
|
||||
result: true,
|
||||
},
|
||||
"false": {
|
||||
alwaysSetCookie: "false",
|
||||
},
|
||||
"set empty": {
|
||||
alwaysSetCookie: "",
|
||||
},
|
||||
"error": {
|
||||
alwaysSetCookie: "error string",
|
||||
},
|
||||
}
|
||||
|
||||
for n, tc := range testCases {
|
||||
cfg := ReadConfig(map[string]string{"global-auth-always-set-cookie": tc.alwaysSetCookie})
|
||||
if cfg.GlobalExternalAuth.AlwaysSetCookie != tc.result {
|
||||
t.Errorf("Testing %v. Expected \"%v\" but \"%v\" was returned", n, tc.result, cfg.GlobalExternalAuth.AlwaysSetCookie)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalExternalAuthSigninRedirectParamParsing(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
param string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue