Skip to content

Support different OIDC issuer hostnames for frontend/backend endpoints #14633

Closed
@heruan

Description

@heruan

Expected Behavior

When the OIDC provider uses different hostnames from frontend and backend endpoints, fetching metadata from the configure issuer hostname does not fail.

Current Behavior

If the frontend and backend hostnames differs when fetching metadata, a validation exception is thrown.

Context

Consider a Spring application running inside a Kubernetes cluster, and it needs to authenticate against an OIDC server inside the same cluster (say Keycloak). Hostnames used inside the cluster are different from the public ones, and this is supported by Keycloak (frontend and backend hostnames can be different).

The Spring app has this configuration:

spring.security.oauth2.client.provider.keycloak.issuer-uri: http://internal:8180/realms/foo

When fetching metadata from there, Keycloak returns:

{
    "issuer": "https://external/realms/foo",
    "authorization_endpoint": "https://external/realms/foo/protocol/openid-connect/auth",
    "token_endpoint": "http://internal:8180/realms/foo/protocol/openid-connect/token",
    "introspection_endpoint": "http://internal:8180/realms/foo/protocol/openid-connect/token/introspect",
    "userinfo_endpoint": "http://internal:8180/realms/foo/protocol/openid-connect/userinfo",
    "end_session_endpoint": "https://external/realms/foo/protocol/openid-connect/logout",
    "...": "..."
}

As expected, the frontend endpoints use https://external and backend endpoints use http://internal:8180.

The problem is that when fetching metadata, Spring fails here:

Assert.state(issuer.equals(metadataIssuer),
() -> "The Issuer \"" + metadataIssuer + "\" provided in the configuration metadata did "
+ "not match the requested issuer \"" + issuer + "\"");

Fetching metadata from the issuer is necessary since some endpoints are read only from metadata, e.g the end_session_endpoint:

ProviderDetails providerDetails = clientRegistration.getProviderDetails();
Object endSessionEndpoint = providerDetails.getConfigurationMetadata().get("end_session_endpoint");

But also other back-channel endpoints without configuration properties in application.yaml.

Since I know both internal and external hostnames, how can I make Spring Security fetch metadata from the internal issuer hostname and accept the external hostname in metadata?

Note: a similar scenario has been solved for JWT decoders in #10309

Metadata

Metadata

Assignees

Labels

in: oauth2An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose)status: invalidAn issue that we don't feel is validtype: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions