From 896d6a690a3659ddf17e8fc5ca56093a28369dcf Mon Sep 17 00:00:00 2001 From: Huabing Zhao Date: Fri, 12 Jan 2024 11:59:02 +0800 Subject: [PATCH] add redirectURL and signoutPath to OIDC (#2409) * add redirectURL and signoutPath to OIDC Signed-off-by: huabing zhao * address comments Signed-off-by: huabing zhao * change signoutpath to logoutpath Signed-off-by: huabing zhao * fix check Signed-off-by: huabing zhao * modify oidc docs Signed-off-by: huabing zhao --------- Signed-off-by: huabing zhao Co-authored-by: zirain --- api/v1alpha1/oidc_types.go | 20 ++-- api/v1alpha1/zz_generated.deepcopy.go | 10 ++ ...ateway.envoyproxy.io_securitypolicies.yaml | 9 ++ internal/gatewayapi/securitypolicy.go | 47 +++++++- internal/gatewayapi/securitypolicy_test.go | 58 +++++++++ .../testdata/securitypolicy-with-oidc.in.yaml | 42 +------ .../securitypolicy-with-oidc.out.yaml | 111 +++--------------- internal/ir/xds.go | 10 ++ internal/xds/translator/oidc.go | 9 +- .../translator/testdata/in/xds-ir/oidc.yaml | 26 +--- .../testdata/out/xds-ir/oidc.clusters.yaml | 14 --- .../testdata/out/xds-ir/oidc.endpoints.yaml | 12 -- .../testdata/out/xds-ir/oidc.listeners.yaml | 46 +------- .../testdata/out/xds-ir/oidc.routes.yaml | 12 -- site/content/en/latest/api/extension_types.md | 8 +- site/content/en/latest/user/oidc.md | 6 +- 16 files changed, 187 insertions(+), 253 deletions(-) diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go index f690cfd7c56..391ea71425b 100644 --- a/api/v1alpha1/oidc_types.go +++ b/api/v1alpha1/oidc_types.go @@ -36,20 +36,18 @@ type OIDC struct { // specified. // +optional Scopes []string `json:"scopes,omitempty"` + + // The redirect URL to be used in the OIDC + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + // If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" + RedirectURL *string `json:"redirectURL,omitempty"` + + // The path to log a user out, clearing their credential cookies. + // If not specified, uses a default logout path "/logout" + LogoutPath *string `json:"logoutPath,omitempty"` } // OIDCProvider defines the OIDC Provider configuration. -// To make the EG OIDC config easy to use, some of the low-level ouath2 filter -// configuration knobs are hidden from the user, and default values will be provided -// when translating to XDS. For example: -// -// * redirect_uri: uses a default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" -// -// * signout_path: uses a default signout path "/signout" -// -// * redirect_path_matcher: uses a default redirect path matcher "/oauth2/callback" -// -// If we get requests to expose these knobs, we can always do so later. type OIDCProvider struct { // The OIDC Provider's [issuer identifier](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery). // Issuer MUST be a URI RFC 3986 [RFC3986] with a scheme component that MUST diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index ec169ae60f6..9ffe50b4f61 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1950,6 +1950,16 @@ func (in *OIDC) DeepCopyInto(out *OIDC) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.RedirectURL != nil { + in, out := &in.RedirectURL, &out.RedirectURL + *out = new(string) + **out = **in + } + if in.LogoutPath != nil { + in, out := &in.LogoutPath, &out.LogoutPath + *out = new(string) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OIDC. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index f361e9c9d8c..ae3a0489de0 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -300,6 +300,10 @@ spec: required: - name type: object + logoutPath: + description: The path to log a user out, clearing their credential + cookies. If not specified, uses a default logout path "/logout" + type: string provider: description: The OIDC Provider configuration. properties: @@ -323,6 +327,11 @@ spec: required: - issuer type: object + redirectURL: + description: The redirect URL to be used in the OIDC [Authentication + Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" + type: string scopes: description: The OIDC scopes to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index adcac69c42b..c9af4e4ef6a 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -29,6 +29,12 @@ import ( "github.com/envoyproxy/gateway/internal/status" ) +const ( + defaultRedirectURL = "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" + defaultRedirectPath = "/oauth2/callback" + defaultLogoutPath = "/logout" +) + func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.SecurityPolicy, gateways []*GatewayContext, routes []RouteContext, @@ -447,19 +453,58 @@ func (t *Translator) buildOIDC( return nil, err } - if err := validateTokenEndpoint(provider.TokenEndpoint); err != nil { + if err = validateTokenEndpoint(provider.TokenEndpoint); err != nil { return nil, err } scopes := appendOpenidScopeIfNotExist(oidc.Scopes) + var ( + redirectURL = defaultRedirectURL + redirectPath = defaultRedirectPath + logoutPath = defaultLogoutPath + ) + + if oidc.RedirectURL != nil { + path, err := extractRedirectPath(*oidc.RedirectURL) + if err != nil { + return nil, err + } + redirectURL = *oidc.RedirectURL + redirectPath = path + logoutPath = *oidc.LogoutPath + } + return &ir.OIDC{ Provider: *provider, ClientID: oidc.ClientID, ClientSecret: clientSecretBytes, Scopes: scopes, + RedirectURL: redirectURL, + RedirectPath: redirectPath, + LogoutPath: logoutPath, }, nil } +func extractRedirectPath(redirectURL string) (string, error) { + schemeDelimiter := strings.Index(redirectURL, "://") + if schemeDelimiter <= 0 { + return "", fmt.Errorf("invalid redirect URL %s", redirectURL) + } + scheme := redirectURL[:schemeDelimiter] + if scheme != "http" && scheme != "https" && scheme != "%REQ(x-forwarded-proto)%" { + return "", fmt.Errorf("invalid redirect URL %s", redirectURL) + } + hostDelimiter := strings.Index(redirectURL[schemeDelimiter+3:], "/") + if hostDelimiter <= 0 { + return "", fmt.Errorf("invalid redirect URL %s", redirectURL) + } + path := redirectURL[schemeDelimiter+3+hostDelimiter:] + if path == "/" { + return "", fmt.Errorf("invalid redirect URL %s", redirectURL) + } + return path, nil +} + // appendOpenidScopeIfNotExist appends the openid scope to the provided scopes // if it is not already present. // `openid` is a required scope for OIDC. diff --git a/internal/gatewayapi/securitypolicy_test.go b/internal/gatewayapi/securitypolicy_test.go index 88ec49c25a3..28f2510f45d 100644 --- a/internal/gatewayapi/securitypolicy_test.go +++ b/internal/gatewayapi/securitypolicy_test.go @@ -74,3 +74,61 @@ func Test_wildcard2regex(t *testing.T) { }) } } + +func Test_extractRedirectPath(t *testing.T) { + tests := []struct { + name string + redirectURL string + want string + wantErr bool + }{ + { + name: "header value syntax", + redirectURL: "%REQ(x-forwarded-proto)%://%REQ(:authority)%/petstore/oauth2/callback", + want: "/petstore/oauth2/callback", + wantErr: false, + }, + { + name: "without header value syntax", + redirectURL: "https://www.example.com/petstore/oauth2/callback", + want: "/petstore/oauth2/callback", + wantErr: false, + }, + { + name: "with port", + redirectURL: "https://www.example.com:9080/petstore/oauth2/callback", + want: "/petstore/oauth2/callback", + wantErr: false, + }, + { + name: "without path", + redirectURL: "https://www.example.com/", + want: "", + wantErr: true, + }, + { + name: "without path", + redirectURL: "https://www.example.com", + want: "", + wantErr: true, + }, + { + name: "without scheme", + redirectURL: "://www.example.com", + want: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := extractRedirectPath(tt.redirectURL) + if (err != nil) != tt.wantErr { + t.Errorf("extractRedirectPath() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err == nil { + assert.Equalf(t, tt.want, got, "extractRedirectPath(%v)", tt.redirectURL) + } + }) + } +} diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml index 889fbfbfc8e..91fae31ce82 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.in.yaml @@ -43,7 +43,7 @@ httpRoutes: name: httproute-1 spec: hostnames: - - gateway.envoyproxy.io + - www.example.com parentRefs: - namespace: envoy-gateway name: gateway-1 @@ -62,7 +62,7 @@ httpRoutes: name: httproute-2 spec: hostnames: - - gateway.envoyproxy.io + - www.example.com parentRefs: - namespace: envoy-gateway name: gateway-1 @@ -74,21 +74,6 @@ httpRoutes: backendRefs: - name: service-1 port: 8080 -grpcRoutes: -- apiVersion: gateway.networking.k8s.io/v1alpha2 - kind: GRPCRoute - metadata: - namespace: default - name: grpcroute-1 - spec: - parentRefs: - - namespace: envoy-gateway - name: gateway-1 - sectionName: http - rules: - - backendRefs: - - name: service-1 - port: 8080 securityPolicies: - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy @@ -107,6 +92,8 @@ securityPolicies: clientID: "client1.apps.googleusercontent.com" clientSecret: name: "client1-secret" + redirectURL: "https://www.example.com/bar/oauth2/callback" + logoutPath: "/bar/logout" - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -127,22 +114,5 @@ securityPolicies: clientSecret: name: "client2-secret" scopes: ["openid", "email", "profile"] -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: SecurityPolicy - metadata: - namespace: default - name: policy-cross-namespace-secretRef # This policy should attach grpcroute-1 - spec: - targetRef: - group: gateway.networking.k8s.io - kind: GRPCRoute - name: grpcroute-1 - oidc: - provider: - issuer: "https://oauth.bar.com" - authorizationEndpoint: "https://oauth.bar.com/oauth2/v2/auth" - tokenEndpoint: "https://oauth.bar.com/token" - clientID: "client3.bar.foo.com" - clientSecret: - namespace: default - name: "client3-secret" + redirectURL: "https://www.example.com/foo/oauth2/callback" + logoutPath: "/foo/logout" diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml index 01dfc18a280..bd2496ecb77 100644 --- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml +++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml @@ -16,7 +16,7 @@ gateways: protocol: HTTP status: listeners: - - attachedRoutes: 3 + - attachedRoutes: 2 conditions: - lastTransitionTime: null message: Sending translated listener configuration to the data plane @@ -39,40 +39,6 @@ gateways: kind: HTTPRoute - group: gateway.networking.k8s.io kind: GRPCRoute -grpcRoutes: -- apiVersion: gateway.networking.k8s.io/v1alpha2 - kind: GRPCRoute - metadata: - creationTimestamp: null - name: grpcroute-1 - namespace: default - spec: - parentRefs: - - name: gateway-1 - namespace: envoy-gateway - sectionName: http - rules: - - backendRefs: - - name: service-1 - port: 8080 - status: - parents: - - conditions: - - lastTransitionTime: null - message: Route is accepted - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Resolved all the Object references for the Route - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - controllerName: gateway.envoyproxy.io/gatewayclass-controller - parentRef: - name: gateway-1 - namespace: envoy-gateway - sectionName: http httpRoutes: - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute @@ -82,7 +48,7 @@ httpRoutes: namespace: default spec: hostnames: - - gateway.envoyproxy.io + - www.example.com parentRefs: - name: gateway-1 namespace: envoy-gateway @@ -120,7 +86,7 @@ httpRoutes: namespace: default spec: hostnames: - - gateway.envoyproxy.io + - www.example.com parentRefs: - name: gateway-1 namespace: envoy-gateway @@ -180,10 +146,12 @@ securityPolicies: group: null kind: null name: client2-secret + logoutPath: /foo/logout provider: authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth issuer: https://oauth.foo.com tokenEndpoint: https://oauth.foo.com/token + redirectURL: https://www.example.com/foo/oauth2/callback scopes: - openid - email @@ -200,35 +168,6 @@ securityPolicies: reason: Accepted status: "True" type: Accepted -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: SecurityPolicy - metadata: - creationTimestamp: null - name: policy-cross-namespace-secretRef - namespace: default - spec: - oidc: - clientID: client3.bar.foo.com - clientSecret: - group: null - kind: null - name: client3-secret - namespace: default - provider: - authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth - issuer: https://oauth.bar.com - tokenEndpoint: https://oauth.bar.com/token - targetRef: - group: gateway.networking.k8s.io - kind: GRPCRoute - name: grpcroute-1 - status: - conditions: - - lastTransitionTime: null - message: SecurityPolicy has been accepted. - reason: Accepted - status: "True" - type: Accepted - apiVersion: gateway.envoyproxy.io/v1alpha1 kind: SecurityPolicy metadata: @@ -242,8 +181,10 @@ securityPolicies: group: null kind: null name: client1-secret + logoutPath: /bar/logout provider: issuer: https://accounts.google.com + redirectURL: https://www.example.com/bar/oauth2/callback targetRef: group: gateway.networking.k8s.io kind: Gateway @@ -265,7 +206,7 @@ xdsIR: - address: 0.0.0.0 hostnames: - '*' - isHTTP2: true + isHTTP2: false name: envoy-gateway/gateway-1/http path: escapedSlashesAction: UnescapeAndRedirect @@ -284,14 +225,17 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - hostname: gateway.envoyproxy.io - name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + hostname: www.example.com + name: httproute/default/httproute-1/rule/0/match/0/www_example_com oidc: clientID: client2.oauth.foo.com clientSecret: Y2xpZW50MTpzZWNyZXQK + logoutPath: /foo/logout provider: authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth tokenEndpoint: https://oauth.foo.com/token + redirectPath: /foo/oauth2/callback + redirectURL: https://www.example.com/foo/oauth2/callback scopes: - openid - email @@ -312,39 +256,20 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - hostname: gateway.envoyproxy.io - name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io + hostname: www.example.com + name: httproute/default/httproute-2/rule/0/match/0/www_example_com oidc: clientID: client1.apps.googleusercontent.com clientSecret: Y2xpZW50MTpzZWNyZXQK + logoutPath: /bar/logout provider: authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth tokenEndpoint: https://oauth2.googleapis.com/token + redirectPath: /bar/oauth2/callback + redirectURL: https://www.example.com/bar/oauth2/callback scopes: - openid pathMatch: distinct: false name: "" prefix: /bar - - backendWeights: - invalid: 0 - valid: 0 - destination: - name: grpcroute/default/grpcroute-1/rule/0 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8080 - protocol: GRPC - weight: 1 - hostname: '*' - name: grpcroute/default/grpcroute-1/rule/0/match/-1/* - oidc: - clientID: client3.bar.foo.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - provider: - authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth - tokenEndpoint: https://oauth.bar.com/token - scopes: - - openid diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 4db4c43028b..aa24e746802 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -451,6 +451,16 @@ type OIDC struct { // The OIDC scopes to be used in the // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). Scopes []string `json:"scopes,omitempty" yaml:"scopes,omitempty"` + + // The redirect URL to be used in the OIDC + // [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). + RedirectURL string `json:"redirectURL,omitempty"` + + // The path part of the redirect URL + RedirectPath string `json:"redirectPath,omitempty"` + + // The path to log a user out, clearing their credential cookies. + LogoutPath string `json:"logoutPath,omitempty"` } // BasicAuth defines the schema for the HTTP Basic Authentication. diff --git a/internal/xds/translator/oidc.go b/internal/xds/translator/oidc.go index 018ad0a120b..e6945d93352 100644 --- a/internal/xds/translator/oidc.go +++ b/internal/xds/translator/oidc.go @@ -28,9 +28,6 @@ import ( const ( oauth2Filter = "envoy.filters.http.oauth2" defaultTokenEndpointTimeout = 10 - redirectURL = "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" - redirectPathMatcher = "/oauth2/callback" - defaultSignoutPath = "/signout" ) func init() { @@ -131,12 +128,12 @@ func oauth2Config(route *ir.HTTPRoute) (*oauth2v3.OAuth2, error) { }, }, AuthorizationEndpoint: route.OIDC.Provider.AuthorizationEndpoint, - RedirectUri: redirectURL, + RedirectUri: route.OIDC.RedirectURL, RedirectPathMatcher: &matcherv3.PathMatcher{ Rule: &matcherv3.PathMatcher_Path{ Path: &matcherv3.StringMatcher{ MatchPattern: &matcherv3.StringMatcher_Exact{ - Exact: redirectPathMatcher, + Exact: route.OIDC.RedirectPath, }, }, }, @@ -145,7 +142,7 @@ func oauth2Config(route *ir.HTTPRoute) (*oauth2v3.OAuth2, error) { Rule: &matcherv3.PathMatcher_Path{ Path: &matcherv3.StringMatcher{ MatchPattern: &matcherv3.StringMatcher_Exact{ - Exact: defaultSignoutPath, + Exact: route.OIDC.LogoutPath, }, }, }, diff --git a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml index 8593b3dced4..ff1d3fb37ca 100644 --- a/internal/xds/translator/testdata/in/xds-ir/oidc.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/oidc.yaml @@ -28,6 +28,9 @@ http: - openid - email - profile + redirectURL: "https://www.example.com/foo/oauth2/callback" + redirectPath: "/foo/oauth2/callback" + logoutPath: "/foo/logout" - name: "second-route" hostname: "*" pathMatch: @@ -48,23 +51,6 @@ http: - openid - email - profile - - name: "third-route" - hostname: "*" - pathMatch: - exact: "test" - destination: - name: "third-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - oidc: - clientID: test.oauth.bar.com - clientSecret: Y2xpZW50MTpzZWNyZXQK - provider: - authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth - tokenEndpoint: https://oauth.bar.com/token - scopes: - - openid - - email - - profile + redirectURL: "https://www.example.com/bar/oauth2/callback" + redirectPath: "/bar/oauth2/callback" + logoutPath: "/bar/logout" diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml index 5843a79b8f0..7ea2bfaed89 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.clusters.yaml @@ -26,20 +26,6 @@ outlierDetection: {} perConnectionBufferLimitBytes: 32768 type: EDS -- commonLbConfig: - localityWeightedLbConfig: {} - connectTimeout: 10s - dnsLookupFamily: V4_ONLY - edsClusterConfig: - edsConfig: - ads: {} - resourceApiVersion: V3 - serviceName: third-route-dest - lbPolicy: LEAST_REQUEST - name: third-route-dest - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 - type: EDS - commonLbConfig: localityWeightedLbConfig: {} connectTimeout: 10s diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.endpoints.yaml index 475b89a087c..de95bf555b9 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.endpoints.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.endpoints.yaml @@ -22,15 +22,3 @@ loadBalancingWeight: 1 locality: region: second-route-dest/backend/0 -- clusterName: third-route-dest - endpoints: - - lbEndpoints: - - endpoint: - address: - socketAddress: - address: 1.2.3.4 - portValue: 50000 - loadBalancingWeight: 1 - loadBalancingWeight: 1 - locality: - region: third-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml index 2a001af7866..aec460ab569 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.listeners.yaml @@ -39,11 +39,11 @@ forwardBearerToken: true redirectPathMatcher: path: - exact: /oauth2/callback - redirectUri: '%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback' + exact: /foo/oauth2/callback + redirectUri: https://www.example.com/foo/oauth2/callback signoutPath: path: - exact: /signout + exact: /foo/logout tokenEndpoint: cluster: oauth_foo_com_443 timeout: 10s @@ -73,45 +73,11 @@ forwardBearerToken: true redirectPathMatcher: path: - exact: /oauth2/callback - redirectUri: '%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback' + exact: /bar/oauth2/callback + redirectUri: https://www.example.com/bar/oauth2/callback signoutPath: path: - exact: /signout - tokenEndpoint: - cluster: oauth_bar_com_443 - timeout: 10s - uri: https://oauth.bar.com/token - - name: envoy.filters.http.oauth2_third-route - typedConfig: - '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2 - config: - authScopes: - - openid - - email - - profile - authType: BASIC_AUTH - authorizationEndpoint: https://oauth.bar.com/oauth2/v2/auth - credentials: - clientId: test.oauth.bar.com - hmacSecret: - name: third-route/oauth2/hmac_secret - sdsConfig: - ads: {} - resourceApiVersion: V3 - tokenSecret: - name: third-route/oauth2/client_secret - sdsConfig: - ads: {} - resourceApiVersion: V3 - forwardBearerToken: true - redirectPathMatcher: - path: - exact: /oauth2/callback - redirectUri: '%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback' - signoutPath: - path: - exact: /signout + exact: /bar/logout tokenEndpoint: cluster: oauth_bar_com_443 timeout: 10s diff --git a/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml index 74831a07eb8..cffe6c9ebcb 100644 --- a/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/oidc.routes.yaml @@ -7,9 +7,6 @@ envoy.filters.http.oauth2_second-route: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig disabled: true - envoy.filters.http.oauth2_third-route: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - disabled: true virtualHosts: - domains: - '*' @@ -33,12 +30,3 @@ envoy.filters.http.oauth2_second-route: '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig config: {} - - match: - path: test - name: third-route - route: - cluster: third-route-dest - typedPerFilterConfig: - envoy.filters.http.oauth2_third-route: - '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig - config: {} diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index e6a36b130dd..def8eba49b2 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -1337,17 +1337,15 @@ _Appears in:_ | `clientSecret` _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ | The Kubernetes secret which contains the OIDC client secret to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). This is an Opaque secret. The client secret should be stored in the key "client-secret". | | `scopes` _string array_ | The OIDC scopes to be used in the [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). The "openid" scope is always added to the list of scopes if not already specified. | +| `redirectURL` _string_ | The redirect URL to be used in the OIDC [Authentication Request](https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest). If not specified, uses the default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" | +| `logoutPath` _string_ | The path to log a user out, clearing their credential cookies. If not specified, uses a default logout path "/logout" | #### OIDCProvider -OIDCProvider defines the OIDC Provider configuration. To make the EG OIDC config easy to use, some of the low-level ouath2 filter configuration knobs are hidden from the user, and default values will be provided when translating to XDS. For example: - * redirect_uri: uses a default redirect URI "%REQ(x-forwarded-proto)%://%REQ(:authority)%/oauth2/callback" - * signout_path: uses a default signout path "/signout" - * redirect_path_matcher: uses a default redirect path matcher "/oauth2/callback" - If we get requests to expose these knobs, we can always do so later. +OIDCProvider defines the OIDC Provider configuration. _Appears in:_ - [OIDC](#oidc) diff --git a/site/content/en/latest/user/oidc.md b/site/content/en/latest/user/oidc.md index 3983d1530fa..39928ed7fba 100644 --- a/site/content/en/latest/user/oidc.md +++ b/site/content/en/latest/user/oidc.md @@ -32,9 +32,9 @@ providers, including Auth0, Azure AD, Keycloak, Okta, OneLogin, Salesforce, UAA, ### Register an OIDC application -Follow the steps in the [Google OIDC documentation][google-oidc] to register an OIDC application. Please use -`https://www.example.com/oauth2/callback` as the redirect URL when registering the application. `oauth2/callback` is the -default callback path used by Envoy Gateway. +Follow the steps in the [Google OIDC documentation][google-oidc] to register an OIDC application. Please make sure the +redirect URL is set to the one you configured in the SecurityPolicy that you will create in the step below. If you don't +specify a redirect URL in the SecurityPolicy, the default redirect URL is `https:///oauth2/callback`. After registering the application, you should have the following information: * Client ID: The client ID of the OIDC application.