From 5c9f9edc5920a33de5443d141d86ba0960e0a9a6 Mon Sep 17 00:00:00 2001 From: Shawn Kim Date: Mon, 9 Jan 2023 15:33:28 -0800 Subject: [PATCH 1/4] feat: add access token support in the OIDC fix: virtual server template for OIDC.AccessTokenEnable --- .../common/crds/k8s.nginx.org_policies.yaml | 2 + .../crds/k8s.nginx.org_policies.yaml | 2 + docs/content/configuration/policy-resource.md | 4 +- examples/custom-resources/oidc/oidc.yaml | 1 + internal/configs/oidc/oidc_common.conf | 15 +- internal/configs/oidc/openid_connect.js | 15 +- internal/configs/version2/http.go | 19 +- .../version2/nginx-plus.virtualserver.tmpl | 5 + internal/configs/virtualserver.go | 19 +- internal/configs/virtualserver_test.go | 119 +++++----- pkg/apis/configuration/v1/types.go | 19 +- .../configuration/validation/policy_test.go | 218 ++++++++++-------- 12 files changed, 246 insertions(+), 192 deletions(-) diff --git a/deployments/common/crds/k8s.nginx.org_policies.yaml b/deployments/common/crds/k8s.nginx.org_policies.yaml index 20fe9187b9..9017bdeefb 100644 --- a/deployments/common/crds/k8s.nginx.org_policies.yaml +++ b/deployments/common/crds/k8s.nginx.org_policies.yaml @@ -134,6 +134,8 @@ spec: type: string zoneSyncLeeway: type: integer + accessTokenEnable: + type: boolean rateLimit: description: RateLimit defines a rate limit policy. type: object diff --git a/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml b/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml index 20fe9187b9..9017bdeefb 100644 --- a/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml +++ b/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml @@ -134,6 +134,8 @@ spec: type: string zoneSyncLeeway: type: integer + accessTokenEnable: + type: boolean rateLimit: description: RateLimit defines a rate limit policy. type: object diff --git a/docs/content/configuration/policy-resource.md b/docs/content/configuration/policy-resource.md index 077726cd2c..3ed5c7b87d 100644 --- a/docs/content/configuration/policy-resource.md +++ b/docs/content/configuration/policy-resource.md @@ -356,6 +356,7 @@ spec: authEndpoint: https://idp.example.com/openid-connect/auth tokenEndpoint: https://idp.example.com/openid-connect/token jwksURI: https://idp.example.com/openid-connect/certs + accessTokenEnable: true ``` NGINX Plus will pass the ID of an authenticated user to the backend in the HTTP header `username`. @@ -384,7 +385,8 @@ The OIDC policy defines a few internal locations that can't be customized: `/_jw |``jwksURI`` | URL for the JSON Web Key Set (JWK) document provided by your OpenID Connect provider. | ``string`` | Yes | |``scope`` | List of OpenID Connect scopes. Possible values are ``openid``, ``profile``, ``email``, ``address`` and ``phone``. The scope ``openid`` always needs to be present and others can be added concatenating them with a ``+`` sign, for example ``openid+profile+email``. The default is ``openid``. | ``string`` | No | |``redirectURI`` | Allows overriding the default redirect URI. The default is ``/_codexch``. | ``string`` | No | -|``zoneSyncLeeway`` | Specifies the maximum timeout in milliseconds for synchronizing ID tokens and shared values between Ingress Controller pods. The default is ``200``. | ``int`` | No | +|``zoneSyncLeeway`` | Specifies the maximum timeout in milliseconds for synchronizing ID/access tokens and shared values between Ingress Controller pods. The default is ``200``. | ``int`` | No | +|``accessTokenEnable`` | Option of whether Bearer token is used to authorize NGINX to access protected backend. | ``boolean`` | No | {{% /table %}} > **Note**: Only one OIDC policy can be referenced in a VirtualServer and its VirtualServerRoutes. However, the same policy can still be applied to different routes in the VirtualServer and VirtualServerRoutes. diff --git a/examples/custom-resources/oidc/oidc.yaml b/examples/custom-resources/oidc/oidc.yaml index 091ce79aba..9711db74d4 100644 --- a/examples/custom-resources/oidc/oidc.yaml +++ b/examples/custom-resources/oidc/oidc.yaml @@ -10,3 +10,4 @@ spec: tokenEndpoint: http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/token jwksURI: http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs scope: openid+profile+email + accessTokenEnable: true diff --git a/internal/configs/oidc/oidc_common.conf b/internal/configs/oidc/oidc_common.conf index 2fb0023945..26ef21b05b 100644 --- a/internal/configs/oidc/oidc_common.conf +++ b/internal/configs/oidc/oidc_common.conf @@ -17,14 +17,17 @@ map $http_x_forwarded_proto $proto { proxy_cache_path /var/cache/nginx/jwk levels=1 keys_zone=jwk:64k max_size=1m; # Change timeout values to at least the validity period of each token type -keyval_zone zone=oidc_id_tokens:1M timeout=1h sync; -keyval_zone zone=refresh_tokens:1M timeout=8h sync; +keyval_zone zone=oidc_id_tokens:1M timeout=1h sync; +keyval_zone zone=oidc_access_tokens:1M timeout=1h sync; +keyval_zone zone=refresh_tokens:1M timeout=8h sync; #keyval_zone zone=oidc_pkce:128K timeout=90s sync; # Temporary storage for PKCE code verifier. -keyval $cookie_auth_token $session_jwt zone=oidc_id_tokens; # Exchange cookie for JWT -keyval $cookie_auth_token $refresh_token zone=refresh_tokens; # Exchange cookie for refresh token -keyval $request_id $new_session zone=oidc_id_tokens; # For initial session creation -keyval $request_id $new_refresh zone=refresh_tokens; # '' +keyval $cookie_auth_token $session_jwt zone=oidc_id_tokens; # Exchange cookie for ID token(JWT) +keyval $cookie_auth_token $access_token zone=oidc_access_tokens; # Exchange cookie for access token +keyval $cookie_auth_token $refresh_token zone=refresh_tokens; # Exchange cookie for refresh token +keyval $request_id $new_session zone=oidc_id_tokens; # For initial session creation +keyval $request_id $new_access_token zone=oidc_access_tokens; +keyval $request_id $new_refresh zone=refresh_tokens; # '' #keyval $pkce_id $pkce_code_verifier zone=oidc_pkce; auth_jwt_claim_set $jwt_audience aud; # In case aud is an array diff --git a/internal/configs/oidc/openid_connect.js b/internal/configs/oidc/openid_connect.js index b997441bb8..d87cdab964 100644 --- a/internal/configs/oidc/openid_connect.js +++ b/internal/configs/oidc/openid_connect.js @@ -101,9 +101,14 @@ function auth(r, afterSyncCheck) { return; } - // ID Token is valid, update keyval + // Update ID token and access token in the key-value store r.log("OIDC refresh success, updating id_token for " + r.variables.cookie_auth_token); - r.variables.session_jwt = tokenset.id_token; // Update key-value store + r.variables.session_jwt = tokenset.id_token; + if (tokenset.access_token) { + r.variables.access_token = tokenset.access_token; + } else { + r.variables.access_token = ""; + } // Update refresh token (if we got a new one) if (r.variables.refresh_token != tokenset.refresh_token) { @@ -187,6 +192,11 @@ function codeExchange(r) { // Add opaque token to keyval session store r.log("OIDC success, creating session " + r.variables.request_id); r.variables.new_session = tokenset.id_token; // Create key-value store entry + if (tokenset.access_token) { + r.variables.new_access_token = tokenset.access_token; + } else { + r.variables.new_access_token = ""; + } r.headersOut["Set-Cookie"] = "auth_token=" + r.variables.request_id + "; " + r.variables.oidc_cookie_flags; r.return(302, r.variables.redirect_base + r.variables.cookie_auth_redir); } @@ -256,6 +266,7 @@ function validateIdToken(r) { function logout(r) { r.log("OIDC logout for " + r.variables.cookie_auth_token); r.variables.session_jwt = "-"; + r.variables.access_token = "-"; r.variables.refresh_token = "-"; r.return(302, r.variables.oidc_logout_redirect); } diff --git a/internal/configs/version2/http.go b/internal/configs/version2/http.go index 0f068dac4e..5c2e792211 100644 --- a/internal/configs/version2/http.go +++ b/internal/configs/version2/http.go @@ -111,15 +111,16 @@ type EgressMTLS struct { // OIDC holds OIDC configuration data. type OIDC struct { - AuthEndpoint string - ClientID string - ClientSecret string - JwksURI string - Scope string - TokenEndpoint string - RedirectURI string - ZoneSyncLeeway int - AuthExtraArgs string + AuthEndpoint string + ClientID string + ClientSecret string + JwksURI string + Scope string + TokenEndpoint string + RedirectURI string + ZoneSyncLeeway int + AuthExtraArgs string + AccessTokenEnable bool } // WAF defines WAF configuration. diff --git a/internal/configs/version2/nginx-plus.virtualserver.tmpl b/internal/configs/version2/nginx-plus.virtualserver.tmpl index 931be65283..1aff7d1ffc 100644 --- a/internal/configs/version2/nginx-plus.virtualserver.tmpl +++ b/internal/configs/version2/nginx-plus.virtualserver.tmpl @@ -429,6 +429,11 @@ server { {{ $proxyOrGRPC }}_set_header username $jwt_claim_sub; {{ end }} + {{ if $s.OIDC.AccessTokenEnable }} + {{ $proxyOrGRPC }}_set_header Authorization "Bearer $access_token"; + {{ $proxyOrGRPC }}_intercept_errors on; + {{ end }} + {{ with $l.WAF }} app_protect_enable {{ .Enable }}; {{ if .ApPolicy }} diff --git a/internal/configs/virtualserver.go b/internal/configs/virtualserver.go index 0a245dca8a..84b2619790 100644 --- a/internal/configs/virtualserver.go +++ b/internal/configs/virtualserver.go @@ -1052,15 +1052,16 @@ func (p *policiesCfg) addOIDCConfig( } oidcPolCfg.oidc = &version2.OIDC{ - AuthEndpoint: oidc.AuthEndpoint, - AuthExtraArgs: authExtraArgs, - TokenEndpoint: oidc.TokenEndpoint, - JwksURI: oidc.JWKSURI, - ClientID: oidc.ClientID, - ClientSecret: string(clientSecret), - Scope: scope, - RedirectURI: redirectURI, - ZoneSyncLeeway: generateIntFromPointer(oidc.ZoneSyncLeeway, 200), + AuthEndpoint: oidc.AuthEndpoint, + AuthExtraArgs: authExtraArgs, + TokenEndpoint: oidc.TokenEndpoint, + JwksURI: oidc.JWKSURI, + ClientID: oidc.ClientID, + ClientSecret: string(clientSecret), + Scope: scope, + RedirectURI: redirectURI, + ZoneSyncLeeway: generateIntFromPointer(oidc.ZoneSyncLeeway, 200), + AccessTokenEnable: oidc.AccessTokenEnable, } oidcPolCfg.key = polKey } diff --git a/internal/configs/virtualserver_test.go b/internal/configs/virtualserver_test.go index 56b291d119..c6fc69863f 100644 --- a/internal/configs/virtualserver_test.go +++ b/internal/configs/virtualserver_test.go @@ -3136,14 +3136,15 @@ func TestGeneratePolicies(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - AuthEndpoint: "http://example.com/auth", - TokenEndpoint: "http://example.com/token", - JWKSURI: "http://example.com/jwks", - ClientID: "client-id", - ClientSecret: "oidc-secret", - Scope: "scope", - RedirectURI: "/redirect", - ZoneSyncLeeway: createPointerFromInt(20), + AuthEndpoint: "http://example.com/auth", + TokenEndpoint: "http://example.com/token", + JWKSURI: "http://example.com/jwks", + ClientID: "client-id", + ClientSecret: "oidc-secret", + Scope: "scope", + RedirectURI: "/redirect", + ZoneSyncLeeway: createPointerFromInt(20), + AccessTokenEnable: true, }, }, }, @@ -4252,10 +4253,11 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "http://foo.com/bar", - TokenEndpoint: "http://foo.com/bar", - JWKSURI: "http://foo.com/bar", + ClientSecret: "oidc-secret", + AuthEndpoint: "http://foo.com/bar", + TokenEndpoint: "http://foo.com/bar", + JWKSURI: "http://foo.com/bar", + AccessTokenEnable: true, }, }, }, @@ -4298,11 +4300,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientID: "foo", - ClientSecret: "oidc-secret", - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JWKSURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JWKSURI: "https://foo.com/certs", + AccessTokenEnable: true, }, }, }, @@ -4313,11 +4316,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientID: "foo", - ClientSecret: "oidc-secret", - AuthEndpoint: "https://bar.com/auth", - TokenEndpoint: "https://bar.com/token", - JWKSURI: "https://bar.com/certs", + ClientID: "foo", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://bar.com/auth", + TokenEndpoint: "https://bar.com/token", + JWKSURI: "https://bar.com/certs", + AccessTokenEnable: true, }, }, }, @@ -4337,14 +4341,15 @@ func TestGeneratePoliciesFails(t *testing.T) { context: "route", oidcPolCfg: &oidcPolicyCfg{ oidc: &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - ZoneSyncLeeway: 0, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + ZoneSyncLeeway: 0, + AccessTokenEnable: true, }, key: "default/oidc-policy-1", }, @@ -4360,13 +4365,14 @@ func TestGeneratePoliciesFails(t *testing.T) { }, expectedOidc: &oidcPolicyCfg{ oidc: &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + AccessTokenEnable: true, }, key: "default/oidc-policy-1", }, @@ -4391,11 +4397,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JWKSURI: "https://foo.com/certs", - ClientID: "foo", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JWKSURI: "https://foo.com/certs", + ClientID: "foo", + AccessTokenEnable: true, }, }, }, @@ -4406,11 +4413,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "https://bar.com/auth", - TokenEndpoint: "https://bar.com/token", - JWKSURI: "https://bar.com/certs", - ClientID: "bar", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://bar.com/auth", + TokenEndpoint: "https://bar.com/token", + JWKSURI: "https://bar.com/certs", + ClientID: "bar", + AccessTokenEnable: true, }, }, }, @@ -4438,14 +4446,15 @@ func TestGeneratePoliciesFails(t *testing.T) { }, expectedOidc: &oidcPolicyCfg{ &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - ZoneSyncLeeway: 200, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + ZoneSyncLeeway: 200, + AccessTokenEnable: true, }, "default/oidc-policy", }, diff --git a/pkg/apis/configuration/v1/types.go b/pkg/apis/configuration/v1/types.go index fa75b33cfa..e1a3465a95 100644 --- a/pkg/apis/configuration/v1/types.go +++ b/pkg/apis/configuration/v1/types.go @@ -475,15 +475,16 @@ type EgressMTLS struct { // OIDC defines an Open ID Connect policy. type OIDC struct { - AuthEndpoint string `json:"authEndpoint"` - TokenEndpoint string `json:"tokenEndpoint"` - JWKSURI string `json:"jwksURI"` - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - Scope string `json:"scope"` - RedirectURI string `json:"redirectURI"` - ZoneSyncLeeway *int `json:"zoneSyncLeeway"` - AuthExtraArgs []string `json:"authExtraArgs"` + AuthEndpoint string `json:"authEndpoint"` + TokenEndpoint string `json:"tokenEndpoint"` + JWKSURI string `json:"jwksURI"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + Scope string `json:"scope"` + RedirectURI string `json:"redirectURI"` + ZoneSyncLeeway *int `json:"zoneSyncLeeway"` + AuthExtraArgs []string `json:"authExtraArgs"` + AccessTokenEnable bool `json:"accessTokenEnable"` } // WAF defines an WAF policy. diff --git a/pkg/apis/configuration/validation/policy_test.go b/pkg/apis/configuration/validation/policy_test.go index fb8b44eb89..48bbf441d6 100644 --- a/pkg/apis/configuration/validation/policy_test.go +++ b/pkg/apis/configuration/validation/policy_test.go @@ -46,14 +46,15 @@ func TestValidatePolicy(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - AuthExtraArgs: []string{"foo=bar"}, - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(10), + AuthEndpoint: "https://foo.bar/auth", + AuthExtraArgs: []string{"foo=bar"}, + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(10), + AccessTokenEnable: true, }, }, }, @@ -150,12 +151,13 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + AccessTokenEnable: true, }, }, }, @@ -167,12 +169,13 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + AccessTokenEnable: true, }, }, }, @@ -197,13 +200,14 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(-1), + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(-1), + AccessTokenEnable: false, }, }, }, @@ -939,50 +943,54 @@ func TestValidateOIDCValid(t *testing.T) { }{ { oidc: &v1.OIDC{ - AuthEndpoint: "https://accounts.google.com/o/oauth2/v2/auth", - AuthExtraArgs: []string{"foo=bar", "baz=zot"}, - TokenEndpoint: "https://oauth2.googleapis.com/token", - JWKSURI: "https://www.googleapis.com/oauth2/v3/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - RedirectURI: "/foo", - ZoneSyncLeeway: createPointerFromInt(20), + AuthEndpoint: "https://accounts.google.com/o/oauth2/v2/auth", + AuthExtraArgs: []string{"foo=bar", "baz=zot"}, + TokenEndpoint: "https://oauth2.googleapis.com/token", + JWKSURI: "https://www.googleapis.com/oauth2/v3/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + RedirectURI: "/foo", + ZoneSyncLeeway: createPointerFromInt(20), + AccessTokenEnable: true, }, msg: "verify full oidc", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", - RedirectURI: "/_codexe", + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + RedirectURI: "/_codexe", + AccessTokenEnable: true, }, msg: "verify azure endpoint", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/auth", - AuthExtraArgs: []string{"kc_idp_hint=foo"}, - TokenEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "bar", - ClientSecret: "foo", - Scope: "openid", + AuthEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/auth", + AuthExtraArgs: []string{"kc_idp_hint=foo"}, + TokenEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "bar", + ClientSecret: "foo", + Scope: "openid", + AccessTokenEnable: true, }, msg: "domain with port number", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "client", - ClientSecret: "secret", - Scope: "openid", + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "client", + ClientSecret: "secret", + Scope: "openid", + AccessTokenEnable: true, }, msg: "ip address", }, @@ -1010,75 +1018,82 @@ func TestValidateOIDCInvalid(t *testing.T) { }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field token", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field jwk", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientSecret: "ff", - Scope: "openid+profile", + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field clientid", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - Scope: "openid+profile", + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field client secret", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "-ff-", - Scope: "openid+profile", + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "-ff-", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "invalid secret name", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://foo.\bar.com", - TokenEndpoint: "http://keycloak.default", - JWKSURI: "http://keycloak.default", - ClientID: "bar", - ClientSecret: "foo", - Scope: "openid", + AuthEndpoint: "http://foo.\bar.com", + TokenEndpoint: "http://keycloak.default", + JWKSURI: "http://keycloak.default", + ClientID: "bar", + ClientSecret: "foo", + Scope: "openid", + AccessTokenEnable: true, }, msg: "invalid URL", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "$foo$bar", - ClientSecret: "secret", - Scope: "openid", + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "$foo$bar", + ClientSecret: "secret", + Scope: "openid", + AccessTokenEnable: true, }, msg: "invalid chars in clientID", }, @@ -1096,13 +1111,14 @@ func TestValidateOIDCInvalid(t *testing.T) { }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "foobar", - ClientSecret: "secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(-1), + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "foobar", + ClientSecret: "secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(-1), + AccessTokenEnable: true, }, msg: "invalid zoneSyncLeeway value", }, From a9ac4665f2338702a738116ef419fc7c62993744 Mon Sep 17 00:00:00 2001 From: Shawn Kim Date: Thu, 9 Mar 2023 18:02:35 -0800 Subject: [PATCH 2/4] feat: add intercept error enable and fix checking OIDC config data fix: compare OIDC option to enable access token and intercepting error fix: revert --- .../common/crds/k8s.nginx.org_policies.yaml | 2 + .../crds/k8s.nginx.org_policies.yaml | 2 + docs/content/configuration/policy-resource.md | 3 + examples/custom-resources/oidc/oidc.yaml | 1 + internal/configs/oidc/openid_connect.js | 2 +- internal/configs/version2/http.go | 21 +- .../version2/nginx-plus.virtualserver.tmpl | 6 +- internal/configs/virtualserver.go | 21 +- internal/configs/virtualserver_test.go | 137 +++++----- pkg/apis/configuration/v1/types.go | 21 +- .../configuration/validation/policy_test.go | 250 ++++++++++-------- 11 files changed, 253 insertions(+), 213 deletions(-) diff --git a/deployments/common/crds/k8s.nginx.org_policies.yaml b/deployments/common/crds/k8s.nginx.org_policies.yaml index 9017bdeefb..e455907a77 100644 --- a/deployments/common/crds/k8s.nginx.org_policies.yaml +++ b/deployments/common/crds/k8s.nginx.org_policies.yaml @@ -136,6 +136,8 @@ spec: type: integer accessTokenEnable: type: boolean + interceptErrorEnable: + type: boolean rateLimit: description: RateLimit defines a rate limit policy. type: object diff --git a/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml b/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml index 9017bdeefb..e455907a77 100644 --- a/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml +++ b/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml @@ -136,6 +136,8 @@ spec: type: integer accessTokenEnable: type: boolean + interceptErrorEnable: + type: boolean rateLimit: description: RateLimit defines a rate limit policy. type: object diff --git a/docs/content/configuration/policy-resource.md b/docs/content/configuration/policy-resource.md index 3ed5c7b87d..08e83f8f98 100644 --- a/docs/content/configuration/policy-resource.md +++ b/docs/content/configuration/policy-resource.md @@ -357,6 +357,7 @@ spec: tokenEndpoint: https://idp.example.com/openid-connect/token jwksURI: https://idp.example.com/openid-connect/certs accessTokenEnable: true + interceptErrorEnable: false ``` NGINX Plus will pass the ID of an authenticated user to the backend in the HTTP header `username`. @@ -388,6 +389,8 @@ The OIDC policy defines a few internal locations that can't be customized: `/_jw |``zoneSyncLeeway`` | Specifies the maximum timeout in milliseconds for synchronizing ID/access tokens and shared values between Ingress Controller pods. The default is ``200``. | ``int`` | No | |``accessTokenEnable`` | Option of whether Bearer token is used to authorize NGINX to access protected backend. | ``boolean`` | No | {{% /table %}} +|``interceptErrorEnable`` | Option to intercept and redirect "401 Unauthorized" proxied responses to nginx for processing with the `error_page` directive to restart `@do_oidc_flow` if an access token can expire before ID token. | ``boolean`` | No | +{{% /table %}} > **Note**: Only one OIDC policy can be referenced in a VirtualServer and its VirtualServerRoutes. However, the same policy can still be applied to different routes in the VirtualServer and VirtualServerRoutes. diff --git a/examples/custom-resources/oidc/oidc.yaml b/examples/custom-resources/oidc/oidc.yaml index 9711db74d4..ec68107e32 100644 --- a/examples/custom-resources/oidc/oidc.yaml +++ b/examples/custom-resources/oidc/oidc.yaml @@ -11,3 +11,4 @@ spec: jwksURI: http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs scope: openid+profile+email accessTokenEnable: true + interceptErrorEnable: false diff --git a/internal/configs/oidc/openid_connect.js b/internal/configs/oidc/openid_connect.js index d87cdab964..1ec212643a 100644 --- a/internal/configs/oidc/openid_connect.js +++ b/internal/configs/oidc/openid_connect.js @@ -101,7 +101,7 @@ function auth(r, afterSyncCheck) { return; } - // Update ID token and access token in the key-value store + // ID Token is valid, update keyval r.log("OIDC refresh success, updating id_token for " + r.variables.cookie_auth_token); r.variables.session_jwt = tokenset.id_token; if (tokenset.access_token) { diff --git a/internal/configs/version2/http.go b/internal/configs/version2/http.go index 5c2e792211..3bc134577e 100644 --- a/internal/configs/version2/http.go +++ b/internal/configs/version2/http.go @@ -111,16 +111,17 @@ type EgressMTLS struct { // OIDC holds OIDC configuration data. type OIDC struct { - AuthEndpoint string - ClientID string - ClientSecret string - JwksURI string - Scope string - TokenEndpoint string - RedirectURI string - ZoneSyncLeeway int - AuthExtraArgs string - AccessTokenEnable bool + AuthEndpoint string + ClientID string + ClientSecret string + JwksURI string + Scope string + TokenEndpoint string + RedirectURI string + ZoneSyncLeeway int + AuthExtraArgs string + AccessTokenEnable bool + InterceptErrorEnable bool } // WAF defines WAF configuration. diff --git a/internal/configs/version2/nginx-plus.virtualserver.tmpl b/internal/configs/version2/nginx-plus.virtualserver.tmpl index 1aff7d1ffc..0f2e37774d 100644 --- a/internal/configs/version2/nginx-plus.virtualserver.tmpl +++ b/internal/configs/version2/nginx-plus.virtualserver.tmpl @@ -429,9 +429,13 @@ server { {{ $proxyOrGRPC }}_set_header username $jwt_claim_sub; {{ end }} - {{ if $s.OIDC.AccessTokenEnable }} + {{ with $oidc := $s.OIDC }} + {{ if $oidc.AccessTokenEnable }} {{ $proxyOrGRPC }}_set_header Authorization "Bearer $access_token"; + {{ end }} + {{ if $oidc.InterceptErrorEnable }} {{ $proxyOrGRPC }}_intercept_errors on; + {{ end }} {{ end }} {{ with $l.WAF }} diff --git a/internal/configs/virtualserver.go b/internal/configs/virtualserver.go index 84b2619790..5495e62978 100644 --- a/internal/configs/virtualserver.go +++ b/internal/configs/virtualserver.go @@ -1052,16 +1052,17 @@ func (p *policiesCfg) addOIDCConfig( } oidcPolCfg.oidc = &version2.OIDC{ - AuthEndpoint: oidc.AuthEndpoint, - AuthExtraArgs: authExtraArgs, - TokenEndpoint: oidc.TokenEndpoint, - JwksURI: oidc.JWKSURI, - ClientID: oidc.ClientID, - ClientSecret: string(clientSecret), - Scope: scope, - RedirectURI: redirectURI, - ZoneSyncLeeway: generateIntFromPointer(oidc.ZoneSyncLeeway, 200), - AccessTokenEnable: oidc.AccessTokenEnable, + AuthEndpoint: oidc.AuthEndpoint, + AuthExtraArgs: authExtraArgs, + TokenEndpoint: oidc.TokenEndpoint, + JwksURI: oidc.JWKSURI, + ClientID: oidc.ClientID, + ClientSecret: string(clientSecret), + Scope: scope, + RedirectURI: redirectURI, + ZoneSyncLeeway: generateIntFromPointer(oidc.ZoneSyncLeeway, 200), + AccessTokenEnable: oidc.AccessTokenEnable, + InterceptErrorEnable: oidc.InterceptErrorEnable, } oidcPolCfg.key = polKey } diff --git a/internal/configs/virtualserver_test.go b/internal/configs/virtualserver_test.go index c6fc69863f..d2545450bc 100644 --- a/internal/configs/virtualserver_test.go +++ b/internal/configs/virtualserver_test.go @@ -3136,15 +3136,16 @@ func TestGeneratePolicies(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - AuthEndpoint: "http://example.com/auth", - TokenEndpoint: "http://example.com/token", - JWKSURI: "http://example.com/jwks", - ClientID: "client-id", - ClientSecret: "oidc-secret", - Scope: "scope", - RedirectURI: "/redirect", - ZoneSyncLeeway: createPointerFromInt(20), - AccessTokenEnable: true, + AuthEndpoint: "http://example.com/auth", + TokenEndpoint: "http://example.com/token", + JWKSURI: "http://example.com/jwks", + ClientID: "client-id", + ClientSecret: "oidc-secret", + Scope: "scope", + RedirectURI: "/redirect", + ZoneSyncLeeway: createPointerFromInt(20), + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -4253,11 +4254,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "http://foo.com/bar", - TokenEndpoint: "http://foo.com/bar", - JWKSURI: "http://foo.com/bar", - AccessTokenEnable: true, + ClientSecret: "oidc-secret", + AuthEndpoint: "http://foo.com/bar", + TokenEndpoint: "http://foo.com/bar", + JWKSURI: "http://foo.com/bar", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -4300,12 +4302,13 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientID: "foo", - ClientSecret: "oidc-secret", - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JWKSURI: "https://foo.com/certs", - AccessTokenEnable: true, + ClientID: "foo", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JWKSURI: "https://foo.com/certs", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -4316,12 +4319,13 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientID: "foo", - ClientSecret: "oidc-secret", - AuthEndpoint: "https://bar.com/auth", - TokenEndpoint: "https://bar.com/token", - JWKSURI: "https://bar.com/certs", - AccessTokenEnable: true, + ClientID: "foo", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://bar.com/auth", + TokenEndpoint: "https://bar.com/token", + JWKSURI: "https://bar.com/certs", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -4341,15 +4345,16 @@ func TestGeneratePoliciesFails(t *testing.T) { context: "route", oidcPolCfg: &oidcPolicyCfg{ oidc: &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - ZoneSyncLeeway: 0, - AccessTokenEnable: true, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + ZoneSyncLeeway: 0, + AccessTokenEnable: true, + InterceptErrorEnable: false, }, key: "default/oidc-policy-1", }, @@ -4365,14 +4370,15 @@ func TestGeneratePoliciesFails(t *testing.T) { }, expectedOidc: &oidcPolicyCfg{ oidc: &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - AccessTokenEnable: true, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, key: "default/oidc-policy-1", }, @@ -4397,12 +4403,13 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JWKSURI: "https://foo.com/certs", - ClientID: "foo", - AccessTokenEnable: true, + ClientSecret: "oidc-secret", + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JWKSURI: "https://foo.com/certs", + ClientID: "foo", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -4413,12 +4420,13 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "https://bar.com/auth", - TokenEndpoint: "https://bar.com/token", - JWKSURI: "https://bar.com/certs", - ClientID: "bar", - AccessTokenEnable: true, + ClientSecret: "oidc-secret", + AuthEndpoint: "https://bar.com/auth", + TokenEndpoint: "https://bar.com/token", + JWKSURI: "https://bar.com/certs", + ClientID: "bar", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -4446,15 +4454,16 @@ func TestGeneratePoliciesFails(t *testing.T) { }, expectedOidc: &oidcPolicyCfg{ &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - ZoneSyncLeeway: 200, - AccessTokenEnable: true, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + ZoneSyncLeeway: 200, + AccessTokenEnable: true, + InterceptErrorEnable: false, }, "default/oidc-policy", }, diff --git a/pkg/apis/configuration/v1/types.go b/pkg/apis/configuration/v1/types.go index e1a3465a95..13e06e1a9b 100644 --- a/pkg/apis/configuration/v1/types.go +++ b/pkg/apis/configuration/v1/types.go @@ -475,16 +475,17 @@ type EgressMTLS struct { // OIDC defines an Open ID Connect policy. type OIDC struct { - AuthEndpoint string `json:"authEndpoint"` - TokenEndpoint string `json:"tokenEndpoint"` - JWKSURI string `json:"jwksURI"` - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - Scope string `json:"scope"` - RedirectURI string `json:"redirectURI"` - ZoneSyncLeeway *int `json:"zoneSyncLeeway"` - AuthExtraArgs []string `json:"authExtraArgs"` - AccessTokenEnable bool `json:"accessTokenEnable"` + AuthEndpoint string `json:"authEndpoint"` + TokenEndpoint string `json:"tokenEndpoint"` + JWKSURI string `json:"jwksURI"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + Scope string `json:"scope"` + RedirectURI string `json:"redirectURI"` + ZoneSyncLeeway *int `json:"zoneSyncLeeway"` + AuthExtraArgs []string `json:"authExtraArgs"` + AccessTokenEnable bool `json:"accessTokenEnable"` + InterceptErrorEnable bool `json:"interceptErrorEnable"` } // WAF defines an WAF policy. diff --git a/pkg/apis/configuration/validation/policy_test.go b/pkg/apis/configuration/validation/policy_test.go index 48bbf441d6..c641d29806 100644 --- a/pkg/apis/configuration/validation/policy_test.go +++ b/pkg/apis/configuration/validation/policy_test.go @@ -46,15 +46,16 @@ func TestValidatePolicy(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - AuthExtraArgs: []string{"foo=bar"}, - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(10), - AccessTokenEnable: true, + AuthEndpoint: "https://foo.bar/auth", + AuthExtraArgs: []string{"foo=bar"}, + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(10), + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -151,13 +152,14 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - AccessTokenEnable: true, + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -169,13 +171,14 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - AccessTokenEnable: true, + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, }, }, @@ -200,14 +203,15 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(-1), - AccessTokenEnable: false, + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(-1), + AccessTokenEnable: false, + InterceptErrorEnable: false, }, }, }, @@ -943,54 +947,58 @@ func TestValidateOIDCValid(t *testing.T) { }{ { oidc: &v1.OIDC{ - AuthEndpoint: "https://accounts.google.com/o/oauth2/v2/auth", - AuthExtraArgs: []string{"foo=bar", "baz=zot"}, - TokenEndpoint: "https://oauth2.googleapis.com/token", - JWKSURI: "https://www.googleapis.com/oauth2/v3/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - RedirectURI: "/foo", - ZoneSyncLeeway: createPointerFromInt(20), - AccessTokenEnable: true, + AuthEndpoint: "https://accounts.google.com/o/oauth2/v2/auth", + AuthExtraArgs: []string{"foo=bar", "baz=zot"}, + TokenEndpoint: "https://oauth2.googleapis.com/token", + JWKSURI: "https://www.googleapis.com/oauth2/v3/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + RedirectURI: "/foo", + ZoneSyncLeeway: createPointerFromInt(20), + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "verify full oidc", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", - RedirectURI: "/_codexe", - AccessTokenEnable: true, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + RedirectURI: "/_codexe", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "verify azure endpoint", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/auth", - AuthExtraArgs: []string{"kc_idp_hint=foo"}, - TokenEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "bar", - ClientSecret: "foo", - Scope: "openid", - AccessTokenEnable: true, + AuthEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/auth", + AuthExtraArgs: []string{"kc_idp_hint=foo"}, + TokenEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "bar", + ClientSecret: "foo", + Scope: "openid", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "domain with port number", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "client", - ClientSecret: "secret", - Scope: "openid", - AccessTokenEnable: true, + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "client", + ClientSecret: "secret", + Scope: "openid", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "ip address", }, @@ -1018,82 +1026,89 @@ func TestValidateOIDCInvalid(t *testing.T) { }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "missing required field token", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "missing required field jwk", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientSecret: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "missing required field clientid", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "missing required field client secret", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "-ff-", - Scope: "openid+profile", - AccessTokenEnable: true, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "-ff-", + Scope: "openid+profile", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "invalid secret name", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://foo.\bar.com", - TokenEndpoint: "http://keycloak.default", - JWKSURI: "http://keycloak.default", - ClientID: "bar", - ClientSecret: "foo", - Scope: "openid", - AccessTokenEnable: true, + AuthEndpoint: "http://foo.\bar.com", + TokenEndpoint: "http://keycloak.default", + JWKSURI: "http://keycloak.default", + ClientID: "bar", + ClientSecret: "foo", + Scope: "openid", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "invalid URL", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "$foo$bar", - ClientSecret: "secret", - Scope: "openid", - AccessTokenEnable: true, + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "$foo$bar", + ClientSecret: "secret", + Scope: "openid", + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "invalid chars in clientID", }, @@ -1111,14 +1126,15 @@ func TestValidateOIDCInvalid(t *testing.T) { }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "foobar", - ClientSecret: "secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(-1), - AccessTokenEnable: true, + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "foobar", + ClientSecret: "secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(-1), + AccessTokenEnable: true, + InterceptErrorEnable: false, }, msg: "invalid zoneSyncLeeway value", }, From e5982adacf63c35ec4662e1e5b9a25937c562f79 Mon Sep 17 00:00:00 2001 From: Shawn Kim Date: Tue, 14 Mar 2023 02:24:31 -0700 Subject: [PATCH 3/4] fix: remove intercept error from access token feature and update CRD --- .../common/crds/k8s.nginx.org_policies.yaml | 6 +- .../crds/k8s.nginx.org_policies.yaml | 6 +- docs/content/configuration/policy-resource.md | 3 - examples/custom-resources/oidc/oidc.yaml | 1 - internal/configs/version2/http.go | 21 +- .../version2/nginx-plus.virtualserver.tmpl | 3 - internal/configs/virtualserver.go | 21 +- internal/configs/virtualserver_test.go | 137 +++++----- pkg/apis/configuration/v1/types.go | 21 +- .../configuration/validation/policy_test.go | 250 ++++++++---------- 10 files changed, 215 insertions(+), 254 deletions(-) diff --git a/deployments/common/crds/k8s.nginx.org_policies.yaml b/deployments/common/crds/k8s.nginx.org_policies.yaml index e455907a77..b4a24adc0c 100644 --- a/deployments/common/crds/k8s.nginx.org_policies.yaml +++ b/deployments/common/crds/k8s.nginx.org_policies.yaml @@ -114,6 +114,8 @@ spec: description: OIDC defines an Open ID Connect policy. type: object properties: + accessTokenEnable: + type: boolean authEndpoint: type: string authExtraArgs: @@ -134,10 +136,6 @@ spec: type: string zoneSyncLeeway: type: integer - accessTokenEnable: - type: boolean - interceptErrorEnable: - type: boolean rateLimit: description: RateLimit defines a rate limit policy. type: object diff --git a/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml b/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml index e455907a77..b4a24adc0c 100644 --- a/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml +++ b/deployments/helm-chart/crds/k8s.nginx.org_policies.yaml @@ -114,6 +114,8 @@ spec: description: OIDC defines an Open ID Connect policy. type: object properties: + accessTokenEnable: + type: boolean authEndpoint: type: string authExtraArgs: @@ -134,10 +136,6 @@ spec: type: string zoneSyncLeeway: type: integer - accessTokenEnable: - type: boolean - interceptErrorEnable: - type: boolean rateLimit: description: RateLimit defines a rate limit policy. type: object diff --git a/docs/content/configuration/policy-resource.md b/docs/content/configuration/policy-resource.md index 08e83f8f98..3ed5c7b87d 100644 --- a/docs/content/configuration/policy-resource.md +++ b/docs/content/configuration/policy-resource.md @@ -357,7 +357,6 @@ spec: tokenEndpoint: https://idp.example.com/openid-connect/token jwksURI: https://idp.example.com/openid-connect/certs accessTokenEnable: true - interceptErrorEnable: false ``` NGINX Plus will pass the ID of an authenticated user to the backend in the HTTP header `username`. @@ -389,8 +388,6 @@ The OIDC policy defines a few internal locations that can't be customized: `/_jw |``zoneSyncLeeway`` | Specifies the maximum timeout in milliseconds for synchronizing ID/access tokens and shared values between Ingress Controller pods. The default is ``200``. | ``int`` | No | |``accessTokenEnable`` | Option of whether Bearer token is used to authorize NGINX to access protected backend. | ``boolean`` | No | {{% /table %}} -|``interceptErrorEnable`` | Option to intercept and redirect "401 Unauthorized" proxied responses to nginx for processing with the `error_page` directive to restart `@do_oidc_flow` if an access token can expire before ID token. | ``boolean`` | No | -{{% /table %}} > **Note**: Only one OIDC policy can be referenced in a VirtualServer and its VirtualServerRoutes. However, the same policy can still be applied to different routes in the VirtualServer and VirtualServerRoutes. diff --git a/examples/custom-resources/oidc/oidc.yaml b/examples/custom-resources/oidc/oidc.yaml index ec68107e32..9711db74d4 100644 --- a/examples/custom-resources/oidc/oidc.yaml +++ b/examples/custom-resources/oidc/oidc.yaml @@ -11,4 +11,3 @@ spec: jwksURI: http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs scope: openid+profile+email accessTokenEnable: true - interceptErrorEnable: false diff --git a/internal/configs/version2/http.go b/internal/configs/version2/http.go index 3bc134577e..5c2e792211 100644 --- a/internal/configs/version2/http.go +++ b/internal/configs/version2/http.go @@ -111,17 +111,16 @@ type EgressMTLS struct { // OIDC holds OIDC configuration data. type OIDC struct { - AuthEndpoint string - ClientID string - ClientSecret string - JwksURI string - Scope string - TokenEndpoint string - RedirectURI string - ZoneSyncLeeway int - AuthExtraArgs string - AccessTokenEnable bool - InterceptErrorEnable bool + AuthEndpoint string + ClientID string + ClientSecret string + JwksURI string + Scope string + TokenEndpoint string + RedirectURI string + ZoneSyncLeeway int + AuthExtraArgs string + AccessTokenEnable bool } // WAF defines WAF configuration. diff --git a/internal/configs/version2/nginx-plus.virtualserver.tmpl b/internal/configs/version2/nginx-plus.virtualserver.tmpl index 0f2e37774d..29847762ed 100644 --- a/internal/configs/version2/nginx-plus.virtualserver.tmpl +++ b/internal/configs/version2/nginx-plus.virtualserver.tmpl @@ -433,9 +433,6 @@ server { {{ if $oidc.AccessTokenEnable }} {{ $proxyOrGRPC }}_set_header Authorization "Bearer $access_token"; {{ end }} - {{ if $oidc.InterceptErrorEnable }} - {{ $proxyOrGRPC }}_intercept_errors on; - {{ end }} {{ end }} {{ with $l.WAF }} diff --git a/internal/configs/virtualserver.go b/internal/configs/virtualserver.go index 5495e62978..84b2619790 100644 --- a/internal/configs/virtualserver.go +++ b/internal/configs/virtualserver.go @@ -1052,17 +1052,16 @@ func (p *policiesCfg) addOIDCConfig( } oidcPolCfg.oidc = &version2.OIDC{ - AuthEndpoint: oidc.AuthEndpoint, - AuthExtraArgs: authExtraArgs, - TokenEndpoint: oidc.TokenEndpoint, - JwksURI: oidc.JWKSURI, - ClientID: oidc.ClientID, - ClientSecret: string(clientSecret), - Scope: scope, - RedirectURI: redirectURI, - ZoneSyncLeeway: generateIntFromPointer(oidc.ZoneSyncLeeway, 200), - AccessTokenEnable: oidc.AccessTokenEnable, - InterceptErrorEnable: oidc.InterceptErrorEnable, + AuthEndpoint: oidc.AuthEndpoint, + AuthExtraArgs: authExtraArgs, + TokenEndpoint: oidc.TokenEndpoint, + JwksURI: oidc.JWKSURI, + ClientID: oidc.ClientID, + ClientSecret: string(clientSecret), + Scope: scope, + RedirectURI: redirectURI, + ZoneSyncLeeway: generateIntFromPointer(oidc.ZoneSyncLeeway, 200), + AccessTokenEnable: oidc.AccessTokenEnable, } oidcPolCfg.key = polKey } diff --git a/internal/configs/virtualserver_test.go b/internal/configs/virtualserver_test.go index d2545450bc..c6fc69863f 100644 --- a/internal/configs/virtualserver_test.go +++ b/internal/configs/virtualserver_test.go @@ -3136,16 +3136,15 @@ func TestGeneratePolicies(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - AuthEndpoint: "http://example.com/auth", - TokenEndpoint: "http://example.com/token", - JWKSURI: "http://example.com/jwks", - ClientID: "client-id", - ClientSecret: "oidc-secret", - Scope: "scope", - RedirectURI: "/redirect", - ZoneSyncLeeway: createPointerFromInt(20), - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "http://example.com/auth", + TokenEndpoint: "http://example.com/token", + JWKSURI: "http://example.com/jwks", + ClientID: "client-id", + ClientSecret: "oidc-secret", + Scope: "scope", + RedirectURI: "/redirect", + ZoneSyncLeeway: createPointerFromInt(20), + AccessTokenEnable: true, }, }, }, @@ -4254,12 +4253,11 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "http://foo.com/bar", - TokenEndpoint: "http://foo.com/bar", - JWKSURI: "http://foo.com/bar", - AccessTokenEnable: true, - InterceptErrorEnable: false, + ClientSecret: "oidc-secret", + AuthEndpoint: "http://foo.com/bar", + TokenEndpoint: "http://foo.com/bar", + JWKSURI: "http://foo.com/bar", + AccessTokenEnable: true, }, }, }, @@ -4302,13 +4300,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientID: "foo", - ClientSecret: "oidc-secret", - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JWKSURI: "https://foo.com/certs", - AccessTokenEnable: true, - InterceptErrorEnable: false, + ClientID: "foo", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JWKSURI: "https://foo.com/certs", + AccessTokenEnable: true, }, }, }, @@ -4319,13 +4316,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientID: "foo", - ClientSecret: "oidc-secret", - AuthEndpoint: "https://bar.com/auth", - TokenEndpoint: "https://bar.com/token", - JWKSURI: "https://bar.com/certs", - AccessTokenEnable: true, - InterceptErrorEnable: false, + ClientID: "foo", + ClientSecret: "oidc-secret", + AuthEndpoint: "https://bar.com/auth", + TokenEndpoint: "https://bar.com/token", + JWKSURI: "https://bar.com/certs", + AccessTokenEnable: true, }, }, }, @@ -4345,16 +4341,15 @@ func TestGeneratePoliciesFails(t *testing.T) { context: "route", oidcPolCfg: &oidcPolicyCfg{ oidc: &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - ZoneSyncLeeway: 0, - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + ZoneSyncLeeway: 0, + AccessTokenEnable: true, }, key: "default/oidc-policy-1", }, @@ -4370,15 +4365,14 @@ func TestGeneratePoliciesFails(t *testing.T) { }, expectedOidc: &oidcPolicyCfg{ oidc: &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + AccessTokenEnable: true, }, key: "default/oidc-policy-1", }, @@ -4403,13 +4397,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JWKSURI: "https://foo.com/certs", - ClientID: "foo", - AccessTokenEnable: true, - InterceptErrorEnable: false, + ClientSecret: "oidc-secret", + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JWKSURI: "https://foo.com/certs", + ClientID: "foo", + AccessTokenEnable: true, }, }, }, @@ -4420,13 +4413,12 @@ func TestGeneratePoliciesFails(t *testing.T) { }, Spec: conf_v1.PolicySpec{ OIDC: &conf_v1.OIDC{ - ClientSecret: "oidc-secret", - AuthEndpoint: "https://bar.com/auth", - TokenEndpoint: "https://bar.com/token", - JWKSURI: "https://bar.com/certs", - ClientID: "bar", - AccessTokenEnable: true, - InterceptErrorEnable: false, + ClientSecret: "oidc-secret", + AuthEndpoint: "https://bar.com/auth", + TokenEndpoint: "https://bar.com/token", + JWKSURI: "https://bar.com/certs", + ClientID: "bar", + AccessTokenEnable: true, }, }, }, @@ -4454,16 +4446,15 @@ func TestGeneratePoliciesFails(t *testing.T) { }, expectedOidc: &oidcPolicyCfg{ &version2.OIDC{ - AuthEndpoint: "https://foo.com/auth", - TokenEndpoint: "https://foo.com/token", - JwksURI: "https://foo.com/certs", - ClientID: "foo", - ClientSecret: "super_secret_123", - RedirectURI: "/_codexch", - Scope: "openid", - ZoneSyncLeeway: 200, - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://foo.com/auth", + TokenEndpoint: "https://foo.com/token", + JwksURI: "https://foo.com/certs", + ClientID: "foo", + ClientSecret: "super_secret_123", + RedirectURI: "/_codexch", + Scope: "openid", + ZoneSyncLeeway: 200, + AccessTokenEnable: true, }, "default/oidc-policy", }, diff --git a/pkg/apis/configuration/v1/types.go b/pkg/apis/configuration/v1/types.go index 13e06e1a9b..e1a3465a95 100644 --- a/pkg/apis/configuration/v1/types.go +++ b/pkg/apis/configuration/v1/types.go @@ -475,17 +475,16 @@ type EgressMTLS struct { // OIDC defines an Open ID Connect policy. type OIDC struct { - AuthEndpoint string `json:"authEndpoint"` - TokenEndpoint string `json:"tokenEndpoint"` - JWKSURI string `json:"jwksURI"` - ClientID string `json:"clientID"` - ClientSecret string `json:"clientSecret"` - Scope string `json:"scope"` - RedirectURI string `json:"redirectURI"` - ZoneSyncLeeway *int `json:"zoneSyncLeeway"` - AuthExtraArgs []string `json:"authExtraArgs"` - AccessTokenEnable bool `json:"accessTokenEnable"` - InterceptErrorEnable bool `json:"interceptErrorEnable"` + AuthEndpoint string `json:"authEndpoint"` + TokenEndpoint string `json:"tokenEndpoint"` + JWKSURI string `json:"jwksURI"` + ClientID string `json:"clientID"` + ClientSecret string `json:"clientSecret"` + Scope string `json:"scope"` + RedirectURI string `json:"redirectURI"` + ZoneSyncLeeway *int `json:"zoneSyncLeeway"` + AuthExtraArgs []string `json:"authExtraArgs"` + AccessTokenEnable bool `json:"accessTokenEnable"` } // WAF defines an WAF policy. diff --git a/pkg/apis/configuration/validation/policy_test.go b/pkg/apis/configuration/validation/policy_test.go index c641d29806..48bbf441d6 100644 --- a/pkg/apis/configuration/validation/policy_test.go +++ b/pkg/apis/configuration/validation/policy_test.go @@ -46,16 +46,15 @@ func TestValidatePolicy(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - AuthExtraArgs: []string{"foo=bar"}, - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(10), - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://foo.bar/auth", + AuthExtraArgs: []string{"foo=bar"}, + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(10), + AccessTokenEnable: true, }, }, }, @@ -152,14 +151,13 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + AccessTokenEnable: true, }, }, }, @@ -171,14 +169,13 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + AccessTokenEnable: true, }, }, }, @@ -203,15 +200,14 @@ func TestValidatePolicyFails(t *testing.T) { policy: &v1.Policy{ Spec: v1.PolicySpec{ OIDC: &v1.OIDC{ - AuthEndpoint: "https://foo.bar/auth", - TokenEndpoint: "https://foo.bar/token", - JWKSURI: "https://foo.bar/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(-1), - AccessTokenEnable: false, - InterceptErrorEnable: false, + AuthEndpoint: "https://foo.bar/auth", + TokenEndpoint: "https://foo.bar/token", + JWKSURI: "https://foo.bar/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(-1), + AccessTokenEnable: false, }, }, }, @@ -947,58 +943,54 @@ func TestValidateOIDCValid(t *testing.T) { }{ { oidc: &v1.OIDC{ - AuthEndpoint: "https://accounts.google.com/o/oauth2/v2/auth", - AuthExtraArgs: []string{"foo=bar", "baz=zot"}, - TokenEndpoint: "https://oauth2.googleapis.com/token", - JWKSURI: "https://www.googleapis.com/oauth2/v3/certs", - ClientID: "random-string", - ClientSecret: "random-secret", - Scope: "openid", - RedirectURI: "/foo", - ZoneSyncLeeway: createPointerFromInt(20), - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://accounts.google.com/o/oauth2/v2/auth", + AuthExtraArgs: []string{"foo=bar", "baz=zot"}, + TokenEndpoint: "https://oauth2.googleapis.com/token", + JWKSURI: "https://www.googleapis.com/oauth2/v3/certs", + ClientID: "random-string", + ClientSecret: "random-secret", + Scope: "openid", + RedirectURI: "/foo", + ZoneSyncLeeway: createPointerFromInt(20), + AccessTokenEnable: true, }, msg: "verify full oidc", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", - RedirectURI: "/_codexe", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + RedirectURI: "/_codexe", + AccessTokenEnable: true, }, msg: "verify azure endpoint", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/auth", - AuthExtraArgs: []string{"kc_idp_hint=foo"}, - TokenEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "bar", - ClientSecret: "foo", - Scope: "openid", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/auth", + AuthExtraArgs: []string{"kc_idp_hint=foo"}, + TokenEndpoint: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://keycloak.default.svc.cluster.local:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "bar", + ClientSecret: "foo", + Scope: "openid", + AccessTokenEnable: true, }, msg: "domain with port number", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "client", - ClientSecret: "secret", - Scope: "openid", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "client", + ClientSecret: "secret", + Scope: "openid", + AccessTokenEnable: true, }, msg: "ip address", }, @@ -1026,89 +1018,82 @@ func TestValidateOIDCInvalid(t *testing.T) { }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field token", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - ClientID: "ff", - ClientSecret: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + ClientID: "ff", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field jwk", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientSecret: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientSecret: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field clientid", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - Scope: "openid+profile", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "missing required field client secret", }, { oidc: &v1.OIDC{ - AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", - TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", - JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", - ClientID: "ff", - ClientSecret: "-ff-", - Scope: "openid+profile", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/authorize", + TokenEndpoint: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/oauth2/v2.0/token", + JWKSURI: "https://login.microsoftonline.com/dd-fff-eee-1234-9be/discovery/v2.0/keys", + ClientID: "ff", + ClientSecret: "-ff-", + Scope: "openid+profile", + AccessTokenEnable: true, }, msg: "invalid secret name", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://foo.\bar.com", - TokenEndpoint: "http://keycloak.default", - JWKSURI: "http://keycloak.default", - ClientID: "bar", - ClientSecret: "foo", - Scope: "openid", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "http://foo.\bar.com", + TokenEndpoint: "http://keycloak.default", + JWKSURI: "http://keycloak.default", + ClientID: "bar", + ClientSecret: "foo", + Scope: "openid", + AccessTokenEnable: true, }, msg: "invalid URL", }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "$foo$bar", - ClientSecret: "secret", - Scope: "openid", - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "$foo$bar", + ClientSecret: "secret", + Scope: "openid", + AccessTokenEnable: true, }, msg: "invalid chars in clientID", }, @@ -1126,15 +1111,14 @@ func TestValidateOIDCInvalid(t *testing.T) { }, { oidc: &v1.OIDC{ - AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", - TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", - JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", - ClientID: "foobar", - ClientSecret: "secret", - Scope: "openid", - ZoneSyncLeeway: createPointerFromInt(-1), - AccessTokenEnable: true, - InterceptErrorEnable: false, + AuthEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/auth", + TokenEndpoint: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token", + JWKSURI: "http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/certs", + ClientID: "foobar", + ClientSecret: "secret", + Scope: "openid", + ZoneSyncLeeway: createPointerFromInt(-1), + AccessTokenEnable: true, }, msg: "invalid zoneSyncLeeway value", }, From e6af55dc14227a9786884ca19303196e2c7eda8f Mon Sep 17 00:00:00 2001 From: Shawn Kim Date: Thu, 16 Mar 2023 19:45:10 -0700 Subject: [PATCH 4/4] fix: move the position of access token enable option --- internal/configs/version2/nginx-plus.virtualserver.tmpl | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/internal/configs/version2/nginx-plus.virtualserver.tmpl b/internal/configs/version2/nginx-plus.virtualserver.tmpl index 29847762ed..a40aeea15a 100644 --- a/internal/configs/version2/nginx-plus.virtualserver.tmpl +++ b/internal/configs/version2/nginx-plus.virtualserver.tmpl @@ -427,12 +427,9 @@ server { error_page 401 = @do_oidc_flow; auth_jwt_key_request /_jwks_uri; {{ $proxyOrGRPC }}_set_header username $jwt_claim_sub; - {{ end }} - - {{ with $oidc := $s.OIDC }} - {{ if $oidc.AccessTokenEnable }} + {{- if $s.OIDC.AccessTokenEnable }} {{ $proxyOrGRPC }}_set_header Authorization "Bearer $access_token"; - {{ end }} + {{- end }} {{ end }} {{ with $l.WAF }}