mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-28 23:02:15 +00:00
Add userNameAttributeName to ClientRegistration
Fixes gh-4580
This commit is contained in:
parent
7fb3093617
commit
38be35677d
@ -135,6 +135,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(H http) throws Exception {
|
public void init(H http) throws Exception {
|
||||||
|
this.initUserNameAttributeNames();
|
||||||
AuthorizationCodeAuthenticationProvider authenticationProvider = new AuthorizationCodeAuthenticationProvider(
|
AuthorizationCodeAuthenticationProvider authenticationProvider = new AuthorizationCodeAuthenticationProvider(
|
||||||
this.getAuthorizationCodeTokenExchanger(), this.getAccessTokenRepository(),
|
this.getAuthorizationCodeTokenExchanger(), this.getAccessTokenRepository(),
|
||||||
this.getProviderJwtDecoderRegistry(), this.getUserInfoService());
|
this.getProviderJwtDecoderRegistry(), this.getUserInfoService());
|
||||||
@ -162,6 +163,20 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
|
|||||||
this.authorizationResponseMatcher : this.getAuthenticationFilter().getAuthorizationResponseMatcher());
|
this.authorizationResponseMatcher : this.getAuthenticationFilter().getAuthorizationResponseMatcher());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initUserNameAttributeNames() {
|
||||||
|
OAuth2LoginConfigurer.getClientRegistrationRepository(this.getBuilder()).getRegistrations().forEach(registration -> {
|
||||||
|
if (StringUtils.hasText(registration.getProviderDetails().getUserInfoEndpoint().getUri()) &&
|
||||||
|
StringUtils.hasText(registration.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName())) {
|
||||||
|
|
||||||
|
URI userInfoUri = URI.create(registration.getProviderDetails().getUserInfoEndpoint().getUri());
|
||||||
|
if (!this.userNameAttributeNames.containsKey(userInfoUri)) {
|
||||||
|
this.userNameAttributeNames.put(
|
||||||
|
userInfoUri, registration.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> getAuthorizationCodeTokenExchanger() {
|
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> getAuthorizationCodeTokenExchanger() {
|
||||||
if (this.authorizationCodeTokenExchanger == null) {
|
if (this.authorizationCodeTokenExchanger == null) {
|
||||||
this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger();
|
this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger();
|
||||||
@ -192,7 +207,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
|
|||||||
));
|
));
|
||||||
providerMetadata.setAuthorizationEndpoint(this.toURL(providerDetails.getAuthorizationUri()));
|
providerMetadata.setAuthorizationEndpoint(this.toURL(providerDetails.getAuthorizationUri()));
|
||||||
providerMetadata.setTokenEndpoint(this.toURL(providerDetails.getTokenUri()));
|
providerMetadata.setTokenEndpoint(this.toURL(providerDetails.getTokenUri()));
|
||||||
providerMetadata.setUserInfoEndpoint(this.toURL(providerDetails.getUserInfoUri()));
|
providerMetadata.setUserInfoEndpoint(this.toURL(providerDetails.getUserInfoEndpoint().getUri()));
|
||||||
providerMetadata.setJwkSetUri(this.toURL(providerDetails.getJwkSetUri()));
|
providerMetadata.setJwkSetUri(this.toURL(providerDetails.getJwkSetUri()));
|
||||||
NimbusJwtDecoderJwkSupport nimbusJwtDecoderJwkSupport =
|
NimbusJwtDecoderJwkSupport nimbusJwtDecoderJwkSupport =
|
||||||
new NimbusJwtDecoderJwkSupport(providerDetails.getJwkSetUri());
|
new NimbusJwtDecoderJwkSupport(providerDetails.getJwkSetUri());
|
||||||
|
@ -121,7 +121,7 @@ public class ClientRegistration {
|
|||||||
public class ProviderDetails {
|
public class ProviderDetails {
|
||||||
private String authorizationUri;
|
private String authorizationUri;
|
||||||
private String tokenUri;
|
private String tokenUri;
|
||||||
private String userInfoUri;
|
private UserInfoEndpoint userInfoEndpoint = new UserInfoEndpoint();
|
||||||
private String jwkSetUri;
|
private String jwkSetUri;
|
||||||
|
|
||||||
protected ProviderDetails() {
|
protected ProviderDetails() {
|
||||||
@ -143,12 +143,12 @@ public class ClientRegistration {
|
|||||||
this.tokenUri = tokenUri;
|
this.tokenUri = tokenUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserInfoUri() {
|
public UserInfoEndpoint getUserInfoEndpoint() {
|
||||||
return this.userInfoUri;
|
return this.userInfoEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setUserInfoUri(String userInfoUri) {
|
protected void setUserInfoEndpoint(UserInfoEndpoint userInfoEndpoint) {
|
||||||
this.userInfoUri = userInfoUri;
|
this.userInfoEndpoint = userInfoEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJwkSetUri() {
|
public String getJwkSetUri() {
|
||||||
@ -158,6 +158,30 @@ public class ClientRegistration {
|
|||||||
protected void setJwkSetUri(String jwkSetUri) {
|
protected void setJwkSetUri(String jwkSetUri) {
|
||||||
this.jwkSetUri = jwkSetUri;
|
this.jwkSetUri = jwkSetUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class UserInfoEndpoint {
|
||||||
|
private String uri;
|
||||||
|
private String userNameAttributeName;
|
||||||
|
|
||||||
|
protected UserInfoEndpoint() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUri() {
|
||||||
|
return this.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUri(String uri) {
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserNameAttributeName() {
|
||||||
|
return this.userNameAttributeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setUserNameAttributeName(String userNameAttributeName) {
|
||||||
|
this.userNameAttributeName = userNameAttributeName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
@ -170,6 +194,7 @@ public class ClientRegistration {
|
|||||||
protected String authorizationUri;
|
protected String authorizationUri;
|
||||||
protected String tokenUri;
|
protected String tokenUri;
|
||||||
protected String userInfoUri;
|
protected String userInfoUri;
|
||||||
|
protected String userNameAttributeName;
|
||||||
protected String jwkSetUri;
|
protected String jwkSetUri;
|
||||||
protected String clientName;
|
protected String clientName;
|
||||||
protected String clientAlias;
|
protected String clientAlias;
|
||||||
@ -190,6 +215,7 @@ public class ClientRegistration {
|
|||||||
this.authorizationUri(clientRegistrationProperties.getAuthorizationUri());
|
this.authorizationUri(clientRegistrationProperties.getAuthorizationUri());
|
||||||
this.tokenUri(clientRegistrationProperties.getTokenUri());
|
this.tokenUri(clientRegistrationProperties.getTokenUri());
|
||||||
this.userInfoUri(clientRegistrationProperties.getUserInfoUri());
|
this.userInfoUri(clientRegistrationProperties.getUserInfoUri());
|
||||||
|
this.userNameAttributeName(clientRegistrationProperties.getUserNameAttributeName());
|
||||||
this.jwkSetUri(clientRegistrationProperties.getJwkSetUri());
|
this.jwkSetUri(clientRegistrationProperties.getJwkSetUri());
|
||||||
this.clientName(clientRegistrationProperties.getClientName());
|
this.clientName(clientRegistrationProperties.getClientName());
|
||||||
this.clientAlias(clientRegistrationProperties.getClientAlias());
|
this.clientAlias(clientRegistrationProperties.getClientAlias());
|
||||||
@ -206,7 +232,8 @@ public class ClientRegistration {
|
|||||||
}
|
}
|
||||||
this.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri());
|
this.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri());
|
||||||
this.tokenUri(clientRegistration.getProviderDetails().getTokenUri());
|
this.tokenUri(clientRegistration.getProviderDetails().getTokenUri());
|
||||||
this.userInfoUri(clientRegistration.getProviderDetails().getUserInfoUri());
|
this.userInfoUri(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUri());
|
||||||
|
this.userNameAttributeName(clientRegistration.getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName());
|
||||||
this.jwkSetUri(clientRegistration.getProviderDetails().getJwkSetUri());
|
this.jwkSetUri(clientRegistration.getProviderDetails().getJwkSetUri());
|
||||||
this.clientName(clientRegistration.getClientName());
|
this.clientName(clientRegistration.getClientName());
|
||||||
this.clientAlias(clientRegistration.getClientAlias());
|
this.clientAlias(clientRegistration.getClientAlias());
|
||||||
@ -255,6 +282,11 @@ public class ClientRegistration {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder userNameAttributeName(String userNameAttributeName) {
|
||||||
|
this.userNameAttributeName = userNameAttributeName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder jwkSetUri(String jwkSetUri) {
|
public Builder jwkSetUri(String jwkSetUri) {
|
||||||
this.jwkSetUri = jwkSetUri;
|
this.jwkSetUri = jwkSetUri;
|
||||||
return this;
|
return this;
|
||||||
@ -288,7 +320,8 @@ public class ClientRegistration {
|
|||||||
ProviderDetails providerDetails = clientRegistration.new ProviderDetails();
|
ProviderDetails providerDetails = clientRegistration.new ProviderDetails();
|
||||||
providerDetails.setAuthorizationUri(this.authorizationUri);
|
providerDetails.setAuthorizationUri(this.authorizationUri);
|
||||||
providerDetails.setTokenUri(this.tokenUri);
|
providerDetails.setTokenUri(this.tokenUri);
|
||||||
providerDetails.setUserInfoUri(this.userInfoUri);
|
providerDetails.getUserInfoEndpoint().setUri(this.userInfoUri);
|
||||||
|
providerDetails.getUserInfoEndpoint().setUserNameAttributeName(this.userNameAttributeName);
|
||||||
providerDetails.setJwkSetUri(this.jwkSetUri);
|
providerDetails.setJwkSetUri(this.jwkSetUri);
|
||||||
clientRegistration.setProviderDetails(providerDetails);
|
clientRegistration.setProviderDetails(providerDetails);
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ public class ClientRegistrationProperties {
|
|||||||
private String authorizationUri;
|
private String authorizationUri;
|
||||||
private String tokenUri;
|
private String tokenUri;
|
||||||
private String userInfoUri;
|
private String userInfoUri;
|
||||||
|
private String userNameAttributeName;
|
||||||
private String jwkSetUri;
|
private String jwkSetUri;
|
||||||
private String clientName;
|
private String clientName;
|
||||||
private String clientAlias;
|
private String clientAlias;
|
||||||
@ -119,6 +120,14 @@ public class ClientRegistrationProperties {
|
|||||||
this.userInfoUri = userInfoUri;
|
this.userInfoUri = userInfoUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getUserNameAttributeName() {
|
||||||
|
return this.userNameAttributeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserNameAttributeName(String userNameAttributeName) {
|
||||||
|
this.userNameAttributeName = userNameAttributeName;
|
||||||
|
}
|
||||||
|
|
||||||
public String getJwkSetUri() {
|
public String getJwkSetUri() {
|
||||||
return this.jwkSetUri;
|
return this.jwkSetUri;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ public class CustomUserTypesOAuth2UserService implements OAuth2UserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuth2User loadUser(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
|
public OAuth2User loadUser(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
|
||||||
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoUri());
|
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
|
||||||
Class<? extends OAuth2User> customUserType;
|
Class<? extends OAuth2User> customUserType;
|
||||||
if ((customUserType = this.getCustomUserTypes().get(userInfoUri)) == null) {
|
if ((customUserType = this.getCustomUserTypes().get(userInfoUri)) == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -66,7 +66,7 @@ public class DefaultOAuth2UserService implements OAuth2UserService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoUri());
|
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
|
||||||
if (!this.getUserNameAttributeNames().containsKey(userInfoUri)) {
|
if (!this.getUserNameAttributeNames().containsKey(userInfoUri)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Missing required \"user name\" attribute name for UserInfo Endpoint: " + userInfoUri.toString());
|
"Missing required \"user name\" attribute name for UserInfo Endpoint: " + userInfoUri.toString());
|
||||||
|
@ -48,7 +48,7 @@ public class NimbusUserInfoRetriever implements UserInfoRetriever {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> retrieve(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
|
public Map<String, Object> retrieve(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
|
||||||
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoUri());
|
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
|
||||||
BearerAccessToken accessToken = new BearerAccessToken(clientAuthentication.getAccessToken().getTokenValue());
|
BearerAccessToken accessToken = new BearerAccessToken(clientAuthentication.getAccessToken().getTokenValue());
|
||||||
|
|
||||||
UserInfoRequest userInfoRequest = new UserInfoRequest(userInfoUri, accessToken);
|
UserInfoRequest userInfoRequest = new UserInfoRequest(userInfoUri, accessToken);
|
||||||
|
@ -23,19 +23,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
|||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||||
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
|
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer;
|
|
||||||
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Joe Grandja
|
* @author Joe Grandja
|
||||||
*/
|
*/
|
||||||
@ -47,44 +40,19 @@ import static org.springframework.boot.autoconfigure.security.oauth2.client.Clie
|
|||||||
@AutoConfigureBefore(SecurityAutoConfiguration.class)
|
@AutoConfigureBefore(SecurityAutoConfiguration.class)
|
||||||
@AutoConfigureAfter(ClientRegistrationAutoConfiguration.class)
|
@AutoConfigureAfter(ClientRegistrationAutoConfiguration.class)
|
||||||
public class OAuth2LoginAutoConfiguration {
|
public class OAuth2LoginAutoConfiguration {
|
||||||
private static final String USER_INFO_URI_PROPERTY = "user-info-uri";
|
|
||||||
private static final String USER_NAME_ATTR_NAME_PROPERTY = "user-name-attribute-name";
|
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
protected static class OAuth2LoginSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
protected static class OAuth2LoginSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||||
private final Environment environment;
|
|
||||||
|
|
||||||
protected OAuth2LoginSecurityConfiguration(Environment environment) {
|
|
||||||
this.environment = environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
http
|
http
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers("/favicon.ico").permitAll()
|
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
.and()
|
.and()
|
||||||
.oauth2Login();
|
.oauth2Login();
|
||||||
|
|
||||||
this.registerUserNameAttributeNames(http.oauth2Login());
|
|
||||||
}
|
}
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
private void registerUserNameAttributeNames(OAuth2LoginConfigurer<HttpSecurity> oauth2LoginConfigurer) throws Exception {
|
|
||||||
Set<String> clientPropertyKeys = resolveClientPropertyKeys(this.environment);
|
|
||||||
for (String clientPropertyKey : clientPropertyKeys) {
|
|
||||||
String fullClientPropertyKey = CLIENT_PROPERTY_PREFIX + "." + clientPropertyKey;
|
|
||||||
if (!this.environment.containsProperty(fullClientPropertyKey + "." + CLIENT_ID_PROPERTY)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
String userInfoUriValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_URI_PROPERTY);
|
|
||||||
String userNameAttributeNameValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_NAME_ATTR_NAME_PROPERTY);
|
|
||||||
if (userInfoUriValue != null && userNameAttributeNameValue != null) {
|
|
||||||
oauth2LoginConfigurer.userInfoEndpoint().userNameAttributeName(userNameAttributeNameValue, URI.create(userInfoUriValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ public class MainController {
|
|||||||
Map userAttributes = this.webClient
|
Map userAttributes = this.webClient
|
||||||
.filter(oauth2Credentials(authentication))
|
.filter(oauth2Credentials(authentication))
|
||||||
.get()
|
.get()
|
||||||
.uri(authentication.getClientAuthentication().getClientRegistration().getProviderDetails().getUserInfoUri())
|
.uri(authentication.getClientAuthentication().getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri())
|
||||||
.retrieve()
|
.retrieve()
|
||||||
.bodyToMono(Map.class)
|
.bodyToMono(Map.class)
|
||||||
.block();
|
.block();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user