Add userNameAttributeName to ClientRegistration

Fixes gh-4580
This commit is contained in:
Joe Grandja 2017-09-26 21:55:19 -04:00
parent 7fb3093617
commit 38be35677d
8 changed files with 69 additions and 44 deletions

View File

@ -135,6 +135,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
@Override
public void init(H http) throws Exception {
this.initUserNameAttributeNames();
AuthorizationCodeAuthenticationProvider authenticationProvider = new AuthorizationCodeAuthenticationProvider(
this.getAuthorizationCodeTokenExchanger(), this.getAccessTokenRepository(),
this.getProviderJwtDecoderRegistry(), this.getUserInfoService());
@ -162,6 +163,20 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
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() {
if (this.authorizationCodeTokenExchanger == null) {
this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger();
@ -192,7 +207,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
));
providerMetadata.setAuthorizationEndpoint(this.toURL(providerDetails.getAuthorizationUri()));
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()));
NimbusJwtDecoderJwkSupport nimbusJwtDecoderJwkSupport =
new NimbusJwtDecoderJwkSupport(providerDetails.getJwkSetUri());

View File

@ -121,7 +121,7 @@ public class ClientRegistration {
public class ProviderDetails {
private String authorizationUri;
private String tokenUri;
private String userInfoUri;
private UserInfoEndpoint userInfoEndpoint = new UserInfoEndpoint();
private String jwkSetUri;
protected ProviderDetails() {
@ -143,12 +143,12 @@ public class ClientRegistration {
this.tokenUri = tokenUri;
}
public String getUserInfoUri() {
return this.userInfoUri;
public UserInfoEndpoint getUserInfoEndpoint() {
return this.userInfoEndpoint;
}
protected void setUserInfoUri(String userInfoUri) {
this.userInfoUri = userInfoUri;
protected void setUserInfoEndpoint(UserInfoEndpoint userInfoEndpoint) {
this.userInfoEndpoint = userInfoEndpoint;
}
public String getJwkSetUri() {
@ -158,6 +158,30 @@ public class ClientRegistration {
protected void setJwkSetUri(String 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 {
@ -170,6 +194,7 @@ public class ClientRegistration {
protected String authorizationUri;
protected String tokenUri;
protected String userInfoUri;
protected String userNameAttributeName;
protected String jwkSetUri;
protected String clientName;
protected String clientAlias;
@ -190,6 +215,7 @@ public class ClientRegistration {
this.authorizationUri(clientRegistrationProperties.getAuthorizationUri());
this.tokenUri(clientRegistrationProperties.getTokenUri());
this.userInfoUri(clientRegistrationProperties.getUserInfoUri());
this.userNameAttributeName(clientRegistrationProperties.getUserNameAttributeName());
this.jwkSetUri(clientRegistrationProperties.getJwkSetUri());
this.clientName(clientRegistrationProperties.getClientName());
this.clientAlias(clientRegistrationProperties.getClientAlias());
@ -206,7 +232,8 @@ public class ClientRegistration {
}
this.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri());
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.clientName(clientRegistration.getClientName());
this.clientAlias(clientRegistration.getClientAlias());
@ -255,6 +282,11 @@ public class ClientRegistration {
return this;
}
public Builder userNameAttributeName(String userNameAttributeName) {
this.userNameAttributeName = userNameAttributeName;
return this;
}
public Builder jwkSetUri(String jwkSetUri) {
this.jwkSetUri = jwkSetUri;
return this;
@ -288,7 +320,8 @@ public class ClientRegistration {
ProviderDetails providerDetails = clientRegistration.new ProviderDetails();
providerDetails.setAuthorizationUri(this.authorizationUri);
providerDetails.setTokenUri(this.tokenUri);
providerDetails.setUserInfoUri(this.userInfoUri);
providerDetails.getUserInfoEndpoint().setUri(this.userInfoUri);
providerDetails.getUserInfoEndpoint().setUserNameAttributeName(this.userNameAttributeName);
providerDetails.setJwkSetUri(this.jwkSetUri);
clientRegistration.setProviderDetails(providerDetails);

View File

@ -42,6 +42,7 @@ public class ClientRegistrationProperties {
private String authorizationUri;
private String tokenUri;
private String userInfoUri;
private String userNameAttributeName;
private String jwkSetUri;
private String clientName;
private String clientAlias;
@ -119,6 +120,14 @@ public class ClientRegistrationProperties {
this.userInfoUri = userInfoUri;
}
public String getUserNameAttributeName() {
return this.userNameAttributeName;
}
public void setUserNameAttributeName(String userNameAttributeName) {
this.userNameAttributeName = userNameAttributeName;
}
public String getJwkSetUri() {
return this.jwkSetUri;
}

View File

@ -56,7 +56,7 @@ public class CustomUserTypesOAuth2UserService implements OAuth2UserService {
@Override
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;
if ((customUserType = this.getCustomUserTypes().get(userInfoUri)) == null) {
return null;

View File

@ -66,7 +66,7 @@ public class DefaultOAuth2UserService implements OAuth2UserService {
return null;
}
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoUri());
URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
if (!this.getUserNameAttributeNames().containsKey(userInfoUri)) {
throw new IllegalArgumentException(
"Missing required \"user name\" attribute name for UserInfo Endpoint: " + userInfoUri.toString());

View File

@ -48,7 +48,7 @@ public class NimbusUserInfoRetriever implements UserInfoRetriever {
@Override
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());
UserInfoRequest userInfoRequest = new UserInfoRequest(userInfoUri, accessToken);

View File

@ -23,19 +23,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration;
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.configuration.EnableWebSecurity;
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.configurers.oauth2.client.OAuth2LoginConfigurer;
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
*/
@ -47,44 +40,19 @@ import static org.springframework.boot.autoconfigure.security.oauth2.client.Clie
@AutoConfigureBefore(SecurityAutoConfiguration.class)
@AutoConfigureAfter(ClientRegistrationAutoConfiguration.class)
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
protected static class OAuth2LoginSecurityConfiguration extends WebSecurityConfigurerAdapter {
private final Environment environment;
protected OAuth2LoginSecurityConfiguration(Environment environment) {
this.environment = environment;
}
// @formatter:off
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/favicon.ico").permitAll()
.anyRequest().authenticated()
.and()
.oauth2Login();
this.registerUserNameAttributeNames(http.oauth2Login());
}
// @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));
}
}
}
}
}

View File

@ -49,7 +49,7 @@ public class MainController {
Map userAttributes = this.webClient
.filter(oauth2Credentials(authentication))
.get()
.uri(authentication.getClientAuthentication().getClientRegistration().getProviderDetails().getUserInfoUri())
.uri(authentication.getClientAuthentication().getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri())
.retrieve()
.bodyToMono(Map.class)
.block();