Skip to content

Allow customization of Provider Configuration Metadata for Client Registration #7695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pthorson opened this issue Dec 3, 2019 · 4 comments
Assignees
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose)

Comments

@pthorson
Copy link

pthorson commented Dec 3, 2019

It would be nice to have a means to add entries or modify entries in the ClientRegistration.ProviderDetails.configurationMetadata

The method ClientRegistrations.fromOidcIssuerLocation returns a ClientRegistration.Builder which can be used to further modify the ClientRegistration. The providerConfigurationMetadata can also be overridden, but since it contains a Map, those values returned by the call to the ".well-known" endpoint will be lost.

        .providerConfigurationMetadata( 
        		Collections.singletonMap("end_session_endpoint", "https://myprovider/oidc/logout")
        )

Since build() copies the values into an `unmodifiableMap', the Map also cannot be updated afterwards.

        clientRegistration.getProviderDetails().getConfigurationMetadata()
                    .put("end_session_endpoint", "https://myprovider/oidc/logout");
....
  java.lang.UnsupportedOperationException
        at java.util.Collections$UnmodifiableMap.put(Unknown Source)

My particular use case is to be able to customize the value of the "end_session_endpoint" which is stored in the providerConfigurationMetadata, but this might also be a handy place to store custom values which otherwise would require extending ClientRegistration.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 3, 2019
@jgrandja
Copy link
Contributor

jgrandja commented Dec 6, 2019

@pthorson You can customize the value of the end_session_endpoint as follows:

ClientRegistration registration = ClientRegistrations.fromOidcIssuerLocation("issuer-uri").build();

Map<String, Object> configurationMetadata = registration.getProviderDetails().getConfigurationMetadata();
// TODO update value of end_session_endpoint

ClientRegistration updatedRegistration = ClientRegistration.withClientRegistration(registration)
		.providerConfigurationMetadata(configurationMetadata)
		.build();

NOTE: ClientRegistration.withClientRegistration(registration) is available in 5.2.0.

I'm going to close this issue as I feel I provided you a solution. We can always reopen if need be.

@jgrandja jgrandja closed this as completed Dec 6, 2019
@jgrandja jgrandja self-assigned this Dec 6, 2019
@jgrandja jgrandja added in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 6, 2019
@pthorson
Copy link
Author

OK I was still on 5.2.0 M2. I see the new method now that I have upgraded 5.2.1.

The ClientRegistration Build still sets the Map unmodifiable in its call to create:

	providerDetails.configurationMetadata = Collections.unmodifiableMap(this.configurationMetadata);

So I just have to copy it after grabbing it and then it can be modified and built again:

	Map<String, Object> unmofifiableConfigurationMetadata = clientRegistration.getProviderDetails().getConfigurationMetadata();
	Map<String, Object> configurationMetadata = new HashMap<>(unmofifiableConfigurationMetadata);
	configurationMetadata.put("end_session_endpoint", "my_uri");
	ClientRegistration updatedRegistration = ClientRegistration.withClientRegistration(clientRegistration)
			.providerConfigurationMetadata(configurationMetadata)
			.build();
	return updatedRegistration;

Thank you.

@downvoteit
Copy link

downvoteit commented Jun 5, 2021

Here is a full solution based on Keycloak OpenID for the wanderers.

package com.tb.ws.cscommon.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientProperties;
import org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Configuration
public class ClientRegistrationConfig {

  @Bean
  @ConditionalOnMissingBean({ClientRegistrationRepository.class})
  InMemoryClientRegistrationRepository clientRegistrationRepository(
      OAuth2ClientProperties properties) {
    List<ClientRegistration> registrations =
        OAuth2ClientPropertiesRegistrationAdapter.getClientRegistrations(properties)
            .values()
            .stream()
            .map(
                o ->
                    ClientRegistration.withClientRegistration(o)
                        .providerConfigurationMetadata(
                            Map.of(
                                "end_session_endpoint",
                                "http://127.0.0.1:8080/auth/realms/OAuth2/protocol/openid-connect/logout"))
                        .build())
            .collect(Collectors.toList());

    return new InMemoryClientRegistrationRepository(registrations);
  }
}

We alter properties loading bean required for immutable InMemoryClientRegistrationRepository initialization.

@uavst
Copy link

uavst commented Jul 23, 2024

@pthorson could you please provide the complete class for this customisation?

OK I was still on 5.2.0 M2. I see the new method now that I have upgraded 5.2.1.

The ClientRegistration Build still sets the Map unmodifiable in its call to create:

	providerDetails.configurationMetadata = Collections.unmodifiableMap(this.configurationMetadata);

So I just have to copy it after grabbing it and then it can be modified and built again:

	Map<String, Object> unmofifiableConfigurationMetadata = clientRegistration.getProviderDetails().getConfigurationMetadata();
	Map<String, Object> configurationMetadata = new HashMap<>(unmofifiableConfigurationMetadata);
	configurationMetadata.put("end_session_endpoint", "my_uri");
	ClientRegistration updatedRegistration = ClientRegistration.withClientRegistration(clientRegistration)
			.providerConfigurationMetadata(configurationMetadata)
			.build();
	return updatedRegistration;

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose)
Projects
None yet
Development

No branches or pull requests

5 participants