Use java.util.Function instead of Converter

Fixes gh-4323
This commit is contained in:
Joe Grandja 2017-06-01 16:04:24 -04:00
parent ac6a86fb5f
commit 6c0ecea494
14 changed files with 51 additions and 52 deletions

View File

@ -15,7 +15,6 @@
*/ */
package org.springframework.security.config.annotation.web.configurers.oauth2.client; package org.springframework.security.config.annotation.web.configurers.oauth2.client;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer; import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer;
@ -34,6 +33,7 @@ import org.springframework.util.Assert;
import java.net.URI; import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
/** /**
* @author Joe Grandja * @author Joe Grandja
@ -43,7 +43,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger; private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
private OAuth2UserService userInfoService; private OAuth2UserService userInfoService;
private Map<URI, Converter<ClientHttpResponse, ? extends OAuth2User>> userInfoTypeConverters = new HashMap<>(); private Map<URI, Function<ClientHttpResponse, ? extends OAuth2User>> userInfoTypeConverters = new HashMap<>();
AuthorizationCodeAuthenticationFilterConfigurer() { AuthorizationCodeAuthenticationFilterConfigurer() {
@ -71,7 +71,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
return this; return this;
} }
AuthorizationCodeAuthenticationFilterConfigurer<H> userInfoTypeConverter(Converter<ClientHttpResponse, ? extends OAuth2User> userInfoConverter, URI userInfoUri) { AuthorizationCodeAuthenticationFilterConfigurer<H> userInfoTypeConverter(Function<ClientHttpResponse, ? extends OAuth2User> userInfoConverter, URI userInfoUri) {
Assert.notNull(userInfoConverter, "userInfoConverter cannot be null"); Assert.notNull(userInfoConverter, "userInfoConverter cannot be null");
Assert.notNull(userInfoUri, "userInfoUri cannot be null"); Assert.notNull(userInfoUri, "userInfoUri cannot be null");
this.userInfoTypeConverters.put(userInfoUri, userInfoConverter); this.userInfoTypeConverters.put(userInfoUri, userInfoConverter);

View File

@ -16,7 +16,6 @@
package org.springframework.security.config.annotation.web.configurers.oauth2.client; package org.springframework.security.config.annotation.web.configurers.oauth2.client;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
@ -36,6 +35,7 @@ import org.springframework.util.CollectionUtils;
import java.net.URI; import java.net.URI;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -95,7 +95,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
return this.and(); return this.and();
} }
public OAuth2LoginConfigurer<B> userInfoTypeConverter(Converter<ClientHttpResponse, ? extends OAuth2User> userInfoConverter, URI userInfoUri) { public OAuth2LoginConfigurer<B> userInfoTypeConverter(Function<ClientHttpResponse, ? extends OAuth2User> userInfoConverter, URI userInfoUri) {
Assert.notNull(userInfoConverter, "userInfoConverter cannot be null"); Assert.notNull(userInfoConverter, "userInfoConverter cannot be null");
Assert.notNull(userInfoUri, "userInfoUri cannot be null"); Assert.notNull(userInfoUri, "userInfoUri cannot be null");
OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.userInfoTypeConverter(userInfoConverter, userInfoUri); OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.userInfoTypeConverter(userInfoConverter, userInfoUri);

View File

@ -123,7 +123,7 @@ public class AuthorizationCodeAuthenticationProcessingFilter extends AbstractAut
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException { throws AuthenticationException, IOException, ServletException {
ErrorResponseAttributes authorizationError = this.errorResponseConverter.convert(request); ErrorResponseAttributes authorizationError = this.errorResponseConverter.apply(request);
if (authorizationError != null) { if (authorizationError != null) {
OAuth2Error oauth2Error = new OAuth2Error(authorizationError.getErrorCode(), OAuth2Error oauth2Error = new OAuth2Error(authorizationError.getErrorCode(),
authorizationError.getDescription(), authorizationError.getUri()); authorizationError.getDescription(), authorizationError.getUri());
@ -144,7 +144,7 @@ public class AuthorizationCodeAuthenticationProcessingFilter extends AbstractAut
} }
AuthorizationCodeAuthorizationResponseAttributes authorizationCodeResponseAttributes = AuthorizationCodeAuthorizationResponseAttributes authorizationCodeResponseAttributes =
this.authorizationCodeResponseConverter.convert(request); this.authorizationCodeResponseConverter.apply(request);
AuthorizationCodeAuthenticationToken authRequest = new AuthorizationCodeAuthenticationToken( AuthorizationCodeAuthenticationToken authRequest = new AuthorizationCodeAuthenticationToken(
authorizationCodeResponseAttributes.getCode(), clientRegistration); authorizationCodeResponseAttributes.getCode(), clientRegistration);

View File

@ -15,7 +15,6 @@
*/ */
package org.springframework.security.oauth2.client.user.converter; package org.springframework.security.oauth2.client.user.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
@ -23,9 +22,10 @@ import org.springframework.security.oauth2.core.user.OAuth2User;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
/** /**
* Base implementation of a {@link Converter} that converts a {@link ClientHttpResponse} * Base implementation of a <code>Function</code> that converts a {@link ClientHttpResponse}
* to a specific type of {@link OAuth2User}. * to a specific type of {@link OAuth2User}.
* *
* @author Joe Grandja * @author Joe Grandja
@ -33,14 +33,14 @@ import java.util.Map;
* @see OAuth2User * @see OAuth2User
* @see ClientHttpResponse * @see ClientHttpResponse
*/ */
public abstract class AbstractOAuth2UserConverter<T extends OAuth2User> implements Converter<ClientHttpResponse, T> { public abstract class AbstractOAuth2UserConverter<R extends OAuth2User> implements Function<ClientHttpResponse, R> {
private final HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); private final HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
protected AbstractOAuth2UserConverter() { protected AbstractOAuth2UserConverter() {
} }
@Override @Override
public final T convert(ClientHttpResponse clientHttpResponse) { public final R apply(ClientHttpResponse clientHttpResponse) {
Map<String, Object> userAttributes; Map<String, Object> userAttributes;
try { try {
@ -49,9 +49,9 @@ public abstract class AbstractOAuth2UserConverter<T extends OAuth2User> implemen
throw new IllegalArgumentException("An error occurred reading the UserInfo response: " + ex.getMessage(), ex); throw new IllegalArgumentException("An error occurred reading the UserInfo response: " + ex.getMessage(), ex);
} }
return this.convert(userAttributes); return this.apply(userAttributes);
} }
protected abstract T convert(Map<String, Object> userAttributes); protected abstract R apply(Map<String, Object> userAttributes);
} }

View File

@ -15,16 +15,17 @@
*/ */
package org.springframework.security.oauth2.client.user.converter; package org.springframework.security.oauth2.client.user.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.util.Assert;
import java.io.IOException; import java.io.IOException;
import java.util.function.Function;
/** /**
* An implementation of a {@link Converter} that converts a {@link ClientHttpResponse} * A <code>Function</code> that converts a {@link ClientHttpResponse}
* to a custom type of {@link OAuth2User}, as supplied via the constructor. * to a custom type of {@link OAuth2User}, as supplied via the constructor.
* *
* @author Joe Grandja * @author Joe Grandja
@ -32,20 +33,21 @@ import java.io.IOException;
* @see OAuth2User * @see OAuth2User
* @see ClientHttpResponse * @see ClientHttpResponse
*/ */
public final class CustomOAuth2UserConverter<T extends OAuth2User> implements Converter<ClientHttpResponse, T> { public final class CustomOAuth2UserConverter<R extends OAuth2User> implements Function<ClientHttpResponse, R> {
private final HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); private final HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
private final Class<T> customType; private final Class<R> customType;
public CustomOAuth2UserConverter(Class<T> customType) { public CustomOAuth2UserConverter(Class<R> customType) {
Assert.notNull(customType, "customType cannot be null");
this.customType = customType; this.customType = customType;
} }
@Override @Override
public T convert(ClientHttpResponse clientHttpResponse) { public R apply(ClientHttpResponse clientHttpResponse) {
T user; R user;
try { try {
user = (T) this.jackson2HttpMessageConverter.read(this.customType, clientHttpResponse); user = (R) this.jackson2HttpMessageConverter.read(this.customType, clientHttpResponse);
} catch (IOException ex) { } catch (IOException ex) {
throw new IllegalArgumentException("An error occurred reading the UserInfo response: " + ex.getMessage(), ex); throw new IllegalArgumentException("An error occurred reading the UserInfo response: " + ex.getMessage(), ex);
} }

View File

@ -40,7 +40,7 @@ public final class OAuth2UserConverter extends AbstractOAuth2UserConverter<OAuth
} }
@Override @Override
protected OAuth2User convert(Map<String, Object> userAttributes) { protected OAuth2User apply(Map<String, Object> userAttributes) {
return new DefaultOAuth2User(userAttributes, this.nameAttributeKey); return new DefaultOAuth2User(userAttributes, this.nameAttributeKey);
} }
} }

View File

@ -33,7 +33,7 @@ import java.util.Map;
public final class UserInfoConverter extends AbstractOAuth2UserConverter<UserInfo> { public final class UserInfoConverter extends AbstractOAuth2UserConverter<UserInfo> {
@Override @Override
protected UserInfo convert(Map<String, Object> userAttributes) { protected UserInfo apply(Map<String, Object> userAttributes) {
return new DefaultUserInfo(userAttributes); return new DefaultUserInfo(userAttributes);
} }
} }

View File

@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
/** /**
* {@link org.springframework.core.convert.converter.Converter} implementations * Support classes for converting to {@link org.springframework.security.oauth2.core.user.OAuth2User}.
* for {@link org.springframework.security.oauth2.core.user.OAuth2User}.
*/ */
package org.springframework.security.oauth2.client.user.converter; package org.springframework.security.oauth2.client.user.converter;

View File

@ -22,7 +22,6 @@ import com.nimbusds.oauth2.sdk.http.HTTPResponse;
import com.nimbusds.oauth2.sdk.token.BearerAccessToken; import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
import com.nimbusds.openid.connect.sdk.UserInfoErrorResponse; import com.nimbusds.openid.connect.sdk.UserInfoErrorResponse;
import com.nimbusds.openid.connect.sdk.UserInfoRequest; import com.nimbusds.openid.connect.sdk.UserInfoRequest;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
@ -40,13 +39,14 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
/** /**
* An implementation of an {@link OAuth2UserService} that uses the <b>Nimbus OAuth 2.0 SDK</b> internally. * An implementation of an {@link OAuth2UserService} that uses the <b>Nimbus OAuth 2.0 SDK</b> internally.
* *
* <p> * <p>
* This implementation uses a <code>Map</code> of <code>Converter</code>'s <i>keyed</i> by <code>URI</code>. * This implementation uses a <code>Map</code> of converter's <i>keyed</i> by <code>URI</code>.
* The <code>URI</code> represents the <i>UserInfo Endpoint</i> address and the mapped <code>Converter</code> * The <code>URI</code> represents the <i>UserInfo Endpoint</i> address and the mapped <code>Function</code>
* is capable of converting the <i>UserInfo Response</i> to either an * is capable of converting the <i>UserInfo Response</i> to either an
* {@link OAuth2User} (for a standard <i>OAuth 2.0 Provider</i>) or * {@link OAuth2User} (for a standard <i>OAuth 2.0 Provider</i>) or
* {@link UserInfo} (for an <i>OpenID Connect 1.0 Provider</i>). * {@link UserInfo} (for an <i>OpenID Connect 1.0 Provider</i>).
@ -57,14 +57,13 @@ import java.util.Map;
* @see AuthenticatedPrincipal * @see AuthenticatedPrincipal
* @see OAuth2User * @see OAuth2User
* @see UserInfo * @see UserInfo
* @see Converter
* @see <a target="_blank" href="https://connect2id.com/products/nimbus-oauth-openid-connect-sdk">Nimbus OAuth 2.0 SDK</a> * @see <a target="_blank" href="https://connect2id.com/products/nimbus-oauth-openid-connect-sdk">Nimbus OAuth 2.0 SDK</a>
*/ */
public class NimbusOAuth2UserService implements OAuth2UserService { public class NimbusOAuth2UserService implements OAuth2UserService {
private static final String INVALID_USER_INFO_RESPONSE_ERROR_CODE = "invalid_user_info_response"; private static final String INVALID_USER_INFO_RESPONSE_ERROR_CODE = "invalid_user_info_response";
private final Map<URI, Converter<ClientHttpResponse, ? extends OAuth2User>> userInfoTypeConverters; private final Map<URI, Function<ClientHttpResponse, ? extends OAuth2User>> userInfoTypeConverters;
public NimbusOAuth2UserService(Map<URI, Converter<ClientHttpResponse, ? extends OAuth2User>> userInfoTypeConverters) { public NimbusOAuth2UserService(Map<URI, Function<ClientHttpResponse, ? extends OAuth2User>> userInfoTypeConverters) {
Assert.notEmpty(userInfoTypeConverters, "userInfoTypeConverters cannot be empty"); Assert.notEmpty(userInfoTypeConverters, "userInfoTypeConverters cannot be empty");
this.userInfoTypeConverters = new HashMap<>(userInfoTypeConverters); this.userInfoTypeConverters = new HashMap<>(userInfoTypeConverters);
} }
@ -84,7 +83,7 @@ public class NimbusOAuth2UserService implements OAuth2UserService {
clientRegistration.getProviderDetails().getUserInfoUri(), ex); clientRegistration.getProviderDetails().getUserInfoUri(), ex);
} }
Converter<ClientHttpResponse, ? extends OAuth2User> userInfoConverter = this.userInfoTypeConverters.get(userInfoUri); Function<ClientHttpResponse, ? extends OAuth2User> userInfoConverter = this.userInfoTypeConverters.get(userInfoUri);
if (userInfoConverter == null) { if (userInfoConverter == null) {
throw new IllegalArgumentException("There is no available User Info converter for " + userInfoUri.toString()); throw new IllegalArgumentException("There is no available User Info converter for " + userInfoUri.toString());
} }
@ -118,7 +117,7 @@ public class NimbusOAuth2UserService implements OAuth2UserService {
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
} }
user = userInfoConverter.convert(new NimbusClientHttpResponse(httpResponse)); user = userInfoConverter.apply(new NimbusClientHttpResponse(httpResponse));
} catch (ParseException ex) { } catch (ParseException ex) {
// This error occurs if the User Info Response is not well-formed or invalid // This error occurs if the User Info Response is not well-formed or invalid

View File

@ -15,15 +15,15 @@
*/ */
package org.springframework.security.oauth2.client.web.converter; package org.springframework.security.oauth2.client.web.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.oauth2.core.endpoint.AuthorizationCodeAuthorizationResponseAttributes; import org.springframework.security.oauth2.core.endpoint.AuthorizationCodeAuthorizationResponseAttributes;
import org.springframework.security.oauth2.core.endpoint.OAuth2Parameter; import org.springframework.security.oauth2.core.endpoint.OAuth2Parameter;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.function.Function;
/** /**
* An implementation of a {@link Converter} that converts an <i>OAuth 2.0 Authorization Code Grant Response</i> * A <code>Function</code> that converts an <i>OAuth 2.0 Authorization Code Grant Response</i>
* (in the form of a {@link HttpServletRequest}) to a {@link AuthorizationCodeAuthorizationResponseAttributes}. * (in the form of a {@link HttpServletRequest}) to a {@link AuthorizationCodeAuthorizationResponseAttributes}.
* *
* @author Joe Grandja * @author Joe Grandja
@ -31,10 +31,10 @@ import javax.servlet.http.HttpServletRequest;
* @see AuthorizationCodeAuthorizationResponseAttributes * @see AuthorizationCodeAuthorizationResponseAttributes
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.2">Section 4.1.2 Authorization Code Grant Response</a> * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.2">Section 4.1.2 Authorization Code Grant Response</a>
*/ */
public final class AuthorizationCodeAuthorizationResponseAttributesConverter implements Converter<HttpServletRequest, AuthorizationCodeAuthorizationResponseAttributes> { public final class AuthorizationCodeAuthorizationResponseAttributesConverter implements Function<HttpServletRequest, AuthorizationCodeAuthorizationResponseAttributes> {
@Override @Override
public AuthorizationCodeAuthorizationResponseAttributes convert(HttpServletRequest request) { public AuthorizationCodeAuthorizationResponseAttributes apply(HttpServletRequest request) {
AuthorizationCodeAuthorizationResponseAttributes response; AuthorizationCodeAuthorizationResponseAttributes response;
String code = request.getParameter(OAuth2Parameter.CODE); String code = request.getParameter(OAuth2Parameter.CODE);

View File

@ -15,25 +15,25 @@
*/ */
package org.springframework.security.oauth2.client.web.converter; package org.springframework.security.oauth2.client.web.converter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.oauth2.core.endpoint.ErrorResponseAttributes; import org.springframework.security.oauth2.core.endpoint.ErrorResponseAttributes;
import org.springframework.security.oauth2.core.endpoint.OAuth2Parameter; import org.springframework.security.oauth2.core.endpoint.OAuth2Parameter;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.function.Function;
/** /**
* An implementation of a {@link Converter} that converts an <i>OAuth 2.0 Error Response</i> * A <code>Function</code> that converts an <i>OAuth 2.0 Error Response</i>
* (in the form of a {@link HttpServletRequest}) to a {@link ErrorResponseAttributes}. * (in the form of a {@link HttpServletRequest}) to a {@link ErrorResponseAttributes}.
* *
* @author Joe Grandja * @author Joe Grandja
* @since 5.0 * @since 5.0
* @see ErrorResponseAttributes * @see ErrorResponseAttributes
*/ */
public final class ErrorResponseAttributesConverter implements Converter<HttpServletRequest, ErrorResponseAttributes> { public final class ErrorResponseAttributesConverter implements Function<HttpServletRequest, ErrorResponseAttributes> {
@Override @Override
public ErrorResponseAttributes convert(HttpServletRequest request) { public ErrorResponseAttributes apply(HttpServletRequest request) {
ErrorResponseAttributes response; ErrorResponseAttributes response;
String errorCode = request.getParameter(OAuth2Parameter.ERROR); String errorCode = request.getParameter(OAuth2Parameter.ERROR);

View File

@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
/** /**
* {@link org.springframework.core.convert.converter.Converter} implementations * Support classes for converting <i>OAuth 2.0 Protocol Endpoint Messages</i>.
* for <i>OAuth 2.0 Protocol Endpoint Messages</i>.
*/ */
package org.springframework.security.oauth2.client.web.converter; package org.springframework.security.oauth2.client.web.converter;

View File

@ -410,9 +410,9 @@ NOTE: Non-standard scopes may be defined by a standard _OAuth 2.0 Provider_. Ple
- *authorization-uri* - the URI used by the client to redirect the end-user's user-agent to the _Authorization Server_ in order to obtain authorization from the end-user (the _Resource Owner_). - *authorization-uri* - the URI used by the client to redirect the end-user's user-agent to the _Authorization Server_ in order to obtain authorization from the end-user (the _Resource Owner_).
- *token-uri* - the URI used by the client when exchanging an _Authorization Grant_ (for example, Authorization Code) for an _Access Token_ at the _Authorization Server_. - *token-uri* - the URI used by the client when exchanging an _Authorization Grant_ (for example, Authorization Code) for an _Access Token_ at the _Authorization Server_.
- *user-info-uri* - the URI used by the client to access the protected resource *UserInfo Endpoint*, in order to obtain attributes of the end-user. - *user-info-uri* - the URI used by the client to access the protected resource *UserInfo Endpoint*, in order to obtain attributes of the end-user.
- *user-info-converter* - the `Converter` implementation class used to convert the *UserInfo Response* to a `UserInfo` (_OpenID Connect 1.0 Provider_) or `OAuth2User` instance (_Standard OAuth 2.0 Provider_). - *user-info-converter* - the `java.util.function.Function` implementation class used to convert the *UserInfo Response* to a `UserInfo` (_OpenID Connect 1.0 Provider_) or `OAuth2User` instance (_Standard OAuth 2.0 Provider_).
TIP: The `Converter` implementation class for an _OpenID Connect 1.0 Provider_ is *org.springframework.security.oauth2.client.user.converter.UserInfoConverter* TIP: The `java.util.function.Function` implementation class for an _OpenID Connect 1.0 Provider_ is *org.springframework.security.oauth2.client.user.converter.UserInfoConverter*
and for a standard _OAuth 2.0 Provider_ it's *org.springframework.security.oauth2.client.user.converter.OAuth2UserConverter*. and for a standard _OAuth 2.0 Provider_ it's *org.springframework.security.oauth2.client.user.converter.OAuth2UserConverter*.
- *user-info-name-attribute-key* - the _key_ used to retrieve the *Name* of the end-user from the `Map` of available attributes in `UserInfo` or `OAuth2User`. - *user-info-name-attribute-key* - the _key_ used to retrieve the *Name* of the end-user from the `Map` of available attributes in `UserInfo` or `OAuth2User`.

View File

@ -23,7 +23,6 @@ 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.convert.converter.Converter;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@ -39,6 +38,7 @@ import org.springframework.util.ClassUtils;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.net.URI; import java.net.URI;
import java.util.Set; import java.util.Set;
import java.util.function.Function;
import static org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration.CLIENT_PROPERTY_PREFIX; import static org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration.CLIENT_PROPERTY_PREFIX;
import static org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration.resolveClientPropertyKeys; import static org.springframework.boot.autoconfigure.security.oauth2.client.ClientRegistrationAutoConfiguration.resolveClientPropertyKeys;
@ -87,18 +87,18 @@ public class OAuth2LoginAutoConfiguration {
String userInfoUriValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_URI_PROPERTY); String userInfoUriValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_URI_PROPERTY);
String userInfoConverterTypeValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_CONVERTER_PROPERTY); String userInfoConverterTypeValue = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_CONVERTER_PROPERTY);
if (userInfoUriValue != null && userInfoConverterTypeValue != null) { if (userInfoUriValue != null && userInfoConverterTypeValue != null) {
Class<? extends Converter> userInfoConverterType = ClassUtils.resolveClassName( Class<? extends Function> userInfoConverterType = ClassUtils.resolveClassName(
userInfoConverterTypeValue, this.getClass().getClassLoader()).asSubclass(Converter.class); userInfoConverterTypeValue, this.getClass().getClassLoader()).asSubclass(Function.class);
Converter<ClientHttpResponse, ? extends OAuth2User> userInfoConverter = null; Function<ClientHttpResponse, ? extends OAuth2User> userInfoConverter = null;
if (AbstractOAuth2UserConverter.class.isAssignableFrom(userInfoConverterType)) { if (AbstractOAuth2UserConverter.class.isAssignableFrom(userInfoConverterType)) {
Constructor<? extends Converter> oauth2UserConverterConstructor = ClassUtils.getConstructorIfAvailable(userInfoConverterType, String.class); Constructor<? extends Function> oauth2UserConverterConstructor = ClassUtils.getConstructorIfAvailable(userInfoConverterType, String.class);
if (oauth2UserConverterConstructor != null) { if (oauth2UserConverterConstructor != null) {
String userInfoNameAttributeKey = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_NAME_ATTR_KEY_PROPERTY); String userInfoNameAttributeKey = this.environment.getProperty(fullClientPropertyKey + "." + USER_INFO_NAME_ATTR_KEY_PROPERTY);
userInfoConverter = (Converter<ClientHttpResponse, ? extends OAuth2User>)oauth2UserConverterConstructor.newInstance(userInfoNameAttributeKey); userInfoConverter = (Function<ClientHttpResponse, ? extends OAuth2User>)oauth2UserConverterConstructor.newInstance(userInfoNameAttributeKey);
} }
} }
if (userInfoConverter == null) { if (userInfoConverter == null) {
userInfoConverter = (Converter<ClientHttpResponse, ? extends OAuth2User>)userInfoConverterType.newInstance(); userInfoConverter = (Function<ClientHttpResponse, ? extends OAuth2User>)userInfoConverterType.newInstance();
} }
oauth2LoginConfigurer.userInfoEndpoint().userInfoTypeConverter(userInfoConverter, new URI(userInfoUriValue)); oauth2LoginConfigurer.userInfoEndpoint().userInfoTypeConverter(userInfoConverter, new URI(userInfoUriValue));
} }