diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeAuthenticationFilterConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeAuthenticationFilterConfigurer.java deleted file mode 100644 index cd6a9a05ea..0000000000 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeAuthenticationFilterConfigurer.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2012-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.security.config.annotation.web.configurers.oauth2.client; - -import org.springframework.security.config.annotation.web.HttpSecurityBuilder; -import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer; -import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; -import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationProvider; -import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationToken; -import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticator; -import org.springframework.security.oauth2.client.authentication.AuthorizationGrantAuthenticator; -import org.springframework.security.oauth2.client.authentication.DelegatingAuthorizationGrantAuthenticator; -import org.springframework.security.oauth2.client.authentication.OAuth2UserAuthenticationProvider; -import org.springframework.security.oauth2.client.authentication.jwt.JwtDecoderRegistry; -import org.springframework.security.oauth2.client.authentication.jwt.nimbus.NimbusJwtDecoderRegistry; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.oauth2.client.token.SecurityTokenRepository; -import org.springframework.security.oauth2.client.user.CustomUserTypesOAuth2UserService; -import org.springframework.security.oauth2.client.user.DefaultOAuth2UserService; -import org.springframework.security.oauth2.client.user.DelegatingOAuth2UserService; -import org.springframework.security.oauth2.client.user.OAuth2UserService; -import org.springframework.security.oauth2.client.web.AuthorizationCodeAuthenticationFilter; -import org.springframework.security.oauth2.client.web.AuthorizationGrantTokenExchanger; -import org.springframework.security.oauth2.client.web.nimbus.NimbusAuthorizationCodeTokenExchanger; -import org.springframework.security.oauth2.core.AccessToken; -import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.security.oauth2.oidc.client.authentication.OidcAuthorizationCodeAuthenticator; -import org.springframework.security.oauth2.oidc.client.user.OidcUserService; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.util.Assert; - -import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author Joe Grandja - */ -final class AuthorizationCodeAuthenticationFilterConfigurer, R extends RequestMatcher> extends - AbstractAuthenticationFilterConfigurer, AuthorizationCodeAuthenticationFilter> { - - private R authorizationResponseMatcher; - private AuthorizationGrantAuthenticator authorizationCodeAuthenticator; - private AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger; - private SecurityTokenRepository accessTokenRepository; - private JwtDecoderRegistry jwtDecoderRegistry; - private OAuth2UserService userInfoService; - private Map> customUserTypes = new HashMap<>(); - private GrantedAuthoritiesMapper userAuthoritiesMapper; - - AuthorizationCodeAuthenticationFilterConfigurer() { - super(new AuthorizationCodeAuthenticationFilter(), null); - } - - AuthorizationCodeAuthenticationFilterConfigurer authorizationResponseMatcher(R authorizationResponseMatcher) { - Assert.notNull(authorizationResponseMatcher, "authorizationResponseMatcher cannot be null"); - this.authorizationResponseMatcher = authorizationResponseMatcher; - return this; - } - - AuthorizationCodeAuthenticationFilterConfigurer authorizationCodeTokenExchanger( - AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger) { - - Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null"); - this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger; - return this; - } - - AuthorizationCodeAuthenticationFilterConfigurer accessTokenRepository(SecurityTokenRepository accessTokenRepository) { - Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null"); - this.accessTokenRepository = accessTokenRepository; - return this; - } - - AuthorizationCodeAuthenticationFilterConfigurer jwtDecoderRegistry(JwtDecoderRegistry jwtDecoderRegistry) { - Assert.notNull(jwtDecoderRegistry, "jwtDecoderRegistry cannot be null"); - this.jwtDecoderRegistry = jwtDecoderRegistry; - return this; - } - - AuthorizationCodeAuthenticationFilterConfigurer userInfoService(OAuth2UserService userInfoService) { - Assert.notNull(userInfoService, "userInfoService cannot be null"); - this.userInfoService = userInfoService; - return this; - } - - AuthorizationCodeAuthenticationFilterConfigurer customUserType(Class customUserType, URI userInfoUri) { - Assert.notNull(customUserType, "customUserType cannot be null"); - Assert.notNull(userInfoUri, "userInfoUri cannot be null"); - this.customUserTypes.put(userInfoUri, customUserType); - return this; - } - - AuthorizationCodeAuthenticationFilterConfigurer userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper) { - Assert.notNull(userAuthoritiesMapper, "userAuthoritiesMapper cannot be null"); - this.userAuthoritiesMapper = userAuthoritiesMapper; - return this; - } - - AuthorizationCodeAuthenticationFilterConfigurer clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository) { - Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); - this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); - return this; - } - - String getLoginUrl() { - return super.getLoginPage(); - } - - String getLoginFailureUrl() { - return super.getFailureUrl(); - } - - @Override - public void init(H http) throws Exception { - AuthorizationCodeAuthenticationProvider authorizationCodeAuthenticationProvider = - new AuthorizationCodeAuthenticationProvider(this.getAuthorizationCodeAuthenticator()); - if (this.accessTokenRepository != null) { - authorizationCodeAuthenticationProvider.setAccessTokenRepository(this.accessTokenRepository); - } - authorizationCodeAuthenticationProvider = this.postProcess(authorizationCodeAuthenticationProvider); - http.authenticationProvider(authorizationCodeAuthenticationProvider); - - OAuth2UserAuthenticationProvider oauth2UserAuthenticationProvider = - new OAuth2UserAuthenticationProvider(this.getUserInfoService()); - if (this.userAuthoritiesMapper != null) { - oauth2UserAuthenticationProvider.setAuthoritiesMapper(this.userAuthoritiesMapper); - } - oauth2UserAuthenticationProvider = this.postProcess(oauth2UserAuthenticationProvider); - http.authenticationProvider(oauth2UserAuthenticationProvider); - - super.init(http); - } - - @Override - public void configure(H http) throws Exception { - AuthorizationCodeAuthenticationFilter authFilter = this.getAuthenticationFilter(); - if (this.authorizationResponseMatcher != null) { - authFilter.setAuthorizationResponseMatcher(this.authorizationResponseMatcher); - } - authFilter.setClientRegistrationRepository(OAuth2LoginConfigurer.getClientRegistrationRepository(this.getBuilder())); - super.configure(http); - } - - @Override - protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) { - return (this.authorizationResponseMatcher != null ? - this.authorizationResponseMatcher : this.getAuthenticationFilter().getAuthorizationResponseMatcher()); - } - - private AuthorizationGrantAuthenticator getAuthorizationCodeAuthenticator() { - if (this.authorizationCodeAuthenticator == null) { - List> authenticators = new ArrayList<>(); - authenticators.add(new AuthorizationCodeAuthenticator(this.getAuthorizationCodeTokenExchanger())); - authenticators.add(new OidcAuthorizationCodeAuthenticator( - this.getAuthorizationCodeTokenExchanger(), this.getJwtDecoderRegistry())); - this.authorizationCodeAuthenticator = new DelegatingAuthorizationGrantAuthenticator<>(authenticators);; - } - return this.authorizationCodeAuthenticator; - } - - private AuthorizationGrantTokenExchanger getAuthorizationCodeTokenExchanger() { - if (this.authorizationCodeTokenExchanger == null) { - this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger(); - } - return this.authorizationCodeTokenExchanger; - } - - private JwtDecoderRegistry getJwtDecoderRegistry() { - if (this.jwtDecoderRegistry == null) { - this.jwtDecoderRegistry = new NimbusJwtDecoderRegistry(); - } - return this.jwtDecoderRegistry; - } - - private OAuth2UserService getUserInfoService() { - if (this.userInfoService == null) { - List oauth2UserServices = new ArrayList<>(); - oauth2UserServices.add(new DefaultOAuth2UserService()); - oauth2UserServices.add(new OidcUserService()); - if (!this.customUserTypes.isEmpty()) { - oauth2UserServices.add(new CustomUserTypesOAuth2UserService(this.customUserTypes)); - } - this.userInfoService = new DelegatingOAuth2UserService(oauth2UserServices); - } - return this.userInfoService; - } -} diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeGrantConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeGrantConfigurer.java new file mode 100644 index 0000000000..2ec052bad7 --- /dev/null +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeGrantConfigurer.java @@ -0,0 +1,290 @@ +/* + * Copyright 2012-2017 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.security.config.annotation.web.configurers.oauth2.client; + +import org.springframework.context.ApplicationContext; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.HttpSecurityBuilder; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationProvider; +import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationToken; +import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticator; +import org.springframework.security.oauth2.client.authentication.AuthorizationGrantAuthenticator; +import org.springframework.security.oauth2.client.authentication.DelegatingAuthorizationGrantAuthenticator; +import org.springframework.security.oauth2.client.authentication.OAuth2UserAuthenticationProvider; +import org.springframework.security.oauth2.client.authentication.jwt.JwtDecoderRegistry; +import org.springframework.security.oauth2.client.authentication.jwt.nimbus.NimbusJwtDecoderRegistry; +import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; +import org.springframework.security.oauth2.client.token.SecurityTokenRepository; +import org.springframework.security.oauth2.client.user.CustomUserTypesOAuth2UserService; +import org.springframework.security.oauth2.client.user.DefaultOAuth2UserService; +import org.springframework.security.oauth2.client.user.DelegatingOAuth2UserService; +import org.springframework.security.oauth2.client.user.OAuth2UserService; +import org.springframework.security.oauth2.client.web.AuthorizationCodeAuthenticationFilter; +import org.springframework.security.oauth2.client.web.AuthorizationCodeRequestRedirectFilter; +import org.springframework.security.oauth2.client.web.AuthorizationGrantTokenExchanger; +import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; +import org.springframework.security.oauth2.client.web.AuthorizationRequestUriBuilder; +import org.springframework.security.oauth2.client.web.nimbus.NimbusAuthorizationCodeTokenExchanger; +import org.springframework.security.oauth2.core.AccessToken; +import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.security.oauth2.oidc.client.authentication.OidcAuthorizationCodeAuthenticator; +import org.springframework.security.oauth2.oidc.client.user.OidcUserService; +import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.util.Assert; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A security configurer for the Authorization Code Grant type. + * + * @author Joe Grandja + * @since 5.0 + */ +public class AuthorizationCodeGrantConfigurer> extends + AbstractHttpConfigurer, B> { + + // ***** Authorization Request members + private AuthorizationCodeRequestRedirectFilter authorizationRequestFilter; + private RequestMatcher authorizationRequestMatcher; + private AuthorizationRequestUriBuilder authorizationRequestBuilder; + private AuthorizationRequestRepository authorizationRequestRepository; + + // ***** Authorization Response members + private AuthorizationCodeAuthenticationFilter authorizationResponseFilter; + private RequestMatcher authorizationResponseMatcher; + private AuthorizationGrantAuthenticator authorizationCodeAuthenticator; + private AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger; + private SecurityTokenRepository accessTokenRepository; + private JwtDecoderRegistry jwtDecoderRegistry; + private OAuth2UserService userService; + private Map> customUserTypes = new HashMap<>(); + private GrantedAuthoritiesMapper userAuthoritiesMapper; + + public AuthorizationCodeGrantConfigurer authorizationRequestMatcher(RequestMatcher authorizationRequestMatcher) { + Assert.notNull(authorizationRequestMatcher, "authorizationRequestMatcher cannot be null"); + this.authorizationRequestMatcher = authorizationRequestMatcher; + return this; + } + + public AuthorizationCodeGrantConfigurer authorizationRequestBuilder(AuthorizationRequestUriBuilder authorizationRequestBuilder) { + Assert.notNull(authorizationRequestBuilder, "authorizationRequestBuilder cannot be null"); + this.authorizationRequestBuilder = authorizationRequestBuilder; + return this; + } + + public AuthorizationCodeGrantConfigurer authorizationRequestRepository(AuthorizationRequestRepository authorizationRequestRepository) { + Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null"); + this.authorizationRequestRepository = authorizationRequestRepository; + return this; + } + + public AuthorizationCodeGrantConfigurer authorizationResponseMatcher(RequestMatcher authorizationResponseMatcher) { + Assert.notNull(authorizationResponseMatcher, "authorizationResponseMatcher cannot be null"); + this.authorizationResponseMatcher = authorizationResponseMatcher; + return this; + } + + public AuthorizationCodeGrantConfigurer authorizationCodeAuthenticator( + AuthorizationGrantAuthenticator authorizationCodeAuthenticator) { + + Assert.notNull(authorizationCodeAuthenticator, "authorizationCodeAuthenticator cannot be null"); + this.authorizationCodeAuthenticator = authorizationCodeAuthenticator; + return this; + } + + public AuthorizationCodeGrantConfigurer authorizationCodeTokenExchanger( + AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger) { + + Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null"); + this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger; + return this; + } + + public AuthorizationCodeGrantConfigurer accessTokenRepository(SecurityTokenRepository accessTokenRepository) { + Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null"); + this.accessTokenRepository = accessTokenRepository; + return this; + } + + public AuthorizationCodeGrantConfigurer jwtDecoderRegistry(JwtDecoderRegistry jwtDecoderRegistry) { + Assert.notNull(jwtDecoderRegistry, "jwtDecoderRegistry cannot be null"); + this.jwtDecoderRegistry = jwtDecoderRegistry; + return this; + } + + public AuthorizationCodeGrantConfigurer userService(OAuth2UserService userService) { + Assert.notNull(userService, "userService cannot be null"); + this.userService = userService; + return this; + } + + public AuthorizationCodeGrantConfigurer customUserType(Class customUserType, URI userInfoUri) { + Assert.notNull(customUserType, "customUserType cannot be null"); + Assert.notNull(userInfoUri, "userInfoUri cannot be null"); + this.customUserTypes.put(userInfoUri, customUserType); + return this; + } + + public AuthorizationCodeGrantConfigurer userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper) { + Assert.notNull(userAuthoritiesMapper, "userAuthoritiesMapper cannot be null"); + this.userAuthoritiesMapper = userAuthoritiesMapper; + return this; + } + + public AuthorizationCodeGrantConfigurer clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository) { + Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); + this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); + return this; + } + + @Override + public final void init(B http) throws Exception { + // ***************************************** + // ***** Initialize AuthenticationProvider's + // + // -> AuthorizationCodeAuthenticationProvider + AuthorizationCodeAuthenticationProvider authorizationCodeAuthenticationProvider = + new AuthorizationCodeAuthenticationProvider(this.getAuthorizationCodeAuthenticator()); + if (this.accessTokenRepository != null) { + authorizationCodeAuthenticationProvider.setAccessTokenRepository(this.accessTokenRepository); + } + http.authenticationProvider(this.postProcess(authorizationCodeAuthenticationProvider)); + + // -> OAuth2UserAuthenticationProvider + OAuth2UserAuthenticationProvider oauth2UserAuthenticationProvider = + new OAuth2UserAuthenticationProvider(this.getUserService()); + if (this.userAuthoritiesMapper != null) { + oauth2UserAuthenticationProvider.setAuthoritiesMapper(this.userAuthoritiesMapper); + } + http.authenticationProvider(this.postProcess(oauth2UserAuthenticationProvider)); + + // ************************* + // ***** Initialize Filter's + // + // -> AuthorizationCodeRequestRedirectFilter + this.authorizationRequestFilter = new AuthorizationCodeRequestRedirectFilter( + this.getClientRegistrationRepository()); + if (this.authorizationRequestMatcher != null) { + this.authorizationRequestFilter.setAuthorizationRequestMatcher(this.authorizationRequestMatcher); + } + if (this.authorizationRequestBuilder != null) { + this.authorizationRequestFilter.setAuthorizationUriBuilder(this.authorizationRequestBuilder); + } + if (this.authorizationRequestRepository != null) { + this.authorizationRequestFilter.setAuthorizationRequestRepository(this.authorizationRequestRepository); + } + + // -> AuthorizationCodeAuthenticationFilter + this.authorizationResponseFilter = new AuthorizationCodeAuthenticationFilter(); + this.authorizationResponseFilter.setClientRegistrationRepository(this.getClientRegistrationRepository()); + if (this.authorizationResponseMatcher != null) { + this.authorizationResponseFilter.setAuthorizationResponseMatcher(this.authorizationResponseMatcher); + } + if (this.authorizationRequestRepository != null) { + this.authorizationResponseFilter.setAuthorizationRequestRepository(this.authorizationRequestRepository); + } + } + + @Override + public void configure(B http) throws Exception { + http.addFilter(this.postProcess(this.authorizationRequestFilter)); + + this.authorizationResponseFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class)); + SessionAuthenticationStrategy sessionAuthenticationStrategy = http.getSharedObject(SessionAuthenticationStrategy.class); + if (sessionAuthenticationStrategy != null) { + this.authorizationResponseFilter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy); + } + http.addFilter(this.postProcess(this.authorizationResponseFilter)); + } + + AuthorizationCodeRequestRedirectFilter getAuthorizationRequestFilter() { + return this.authorizationRequestFilter; + } + + RequestMatcher getAuthorizationRequestMatcher() { + return this.authorizationRequestMatcher; + } + + AuthorizationCodeAuthenticationFilter getAuthorizationResponseFilter() { + return this.authorizationResponseFilter; + } + + RequestMatcher getAuthorizationResponseMatcher() { + return this.authorizationResponseMatcher; + } + + AuthorizationRequestRepository getAuthorizationRequestRepository() { + return this.authorizationRequestRepository; + } + + private AuthorizationGrantAuthenticator getAuthorizationCodeAuthenticator() { + if (this.authorizationCodeAuthenticator == null) { + List> authenticators = new ArrayList<>(); + authenticators.add(new AuthorizationCodeAuthenticator(this.getAuthorizationCodeTokenExchanger())); + authenticators.add(new OidcAuthorizationCodeAuthenticator( + this.getAuthorizationCodeTokenExchanger(), this.getJwtDecoderRegistry())); + this.authorizationCodeAuthenticator = new DelegatingAuthorizationGrantAuthenticator<>(authenticators);; + } + return this.authorizationCodeAuthenticator; + } + + private AuthorizationGrantTokenExchanger getAuthorizationCodeTokenExchanger() { + if (this.authorizationCodeTokenExchanger == null) { + this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger(); + } + return this.authorizationCodeTokenExchanger; + } + + private JwtDecoderRegistry getJwtDecoderRegistry() { + if (this.jwtDecoderRegistry == null) { + this.jwtDecoderRegistry = new NimbusJwtDecoderRegistry(); + } + return this.jwtDecoderRegistry; + } + + private OAuth2UserService getUserService() { + if (this.userService == null) { + List userServices = new ArrayList<>(); + userServices.add(new DefaultOAuth2UserService()); + userServices.add(new OidcUserService()); + if (!this.customUserTypes.isEmpty()) { + userServices.add(new CustomUserTypesOAuth2UserService(this.customUserTypes)); + } + this.userService = new DelegatingOAuth2UserService(userServices); + } + return this.userService; + } + + private ClientRegistrationRepository getClientRegistrationRepository() { + ClientRegistrationRepository clientRegistrationRepository = this.getBuilder().getSharedObject(ClientRegistrationRepository.class); + if (clientRegistrationRepository == null) { + clientRegistrationRepository = this.getClientRegistrationRepositoryBean(); + this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); + } + return clientRegistrationRepository; + } + + private ClientRegistrationRepository getClientRegistrationRepositoryBean() { + return this.getBuilder().getSharedObject(ApplicationContext.class).getBean(ClientRegistrationRepository.class); + } +} diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeRequestRedirectFilterConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeRequestRedirectFilterConfigurer.java deleted file mode 100644 index a53d80d53b..0000000000 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeRequestRedirectFilterConfigurer.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2012-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.security.config.annotation.web.configurers.oauth2.client; - -import org.springframework.security.config.annotation.web.HttpSecurityBuilder; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.oauth2.client.web.AuthorizationCodeRequestRedirectFilter; -import org.springframework.security.oauth2.client.web.AuthorizationRequestUriBuilder; -import org.springframework.security.oauth2.client.web.DefaultAuthorizationRequestUriBuilder; -import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.security.web.util.matcher.RequestVariablesExtractor; -import org.springframework.util.Assert; - -/** - * @author Joe Grandja - */ -final class AuthorizationCodeRequestRedirectFilterConfigurer, R extends RequestMatcher & RequestVariablesExtractor> extends - AbstractHttpConfigurer, H> { - - private R authorizationRequestMatcher; - private AuthorizationRequestUriBuilder authorizationRequestBuilder; - - AuthorizationCodeRequestRedirectFilterConfigurer authorizationRequestMatcher(R authorizationRequestMatcher) { - Assert.notNull(authorizationRequestMatcher, "authorizationRequestMatcher cannot be null"); - this.authorizationRequestMatcher = authorizationRequestMatcher; - return this; - } - - AuthorizationCodeRequestRedirectFilterConfigurer authorizationRequestBuilder(AuthorizationRequestUriBuilder authorizationRequestBuilder) { - Assert.notNull(authorizationRequestBuilder, "authorizationRequestBuilder cannot be null"); - this.authorizationRequestBuilder = authorizationRequestBuilder; - return this; - } - - AuthorizationCodeRequestRedirectFilterConfigurer clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository) { - Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); - this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); - return this; - } - - R getAuthorizationRequestMatcher() { - return this.authorizationRequestMatcher; - } - - @Override - public void configure(H http) throws Exception { - AuthorizationCodeRequestRedirectFilter filter = new AuthorizationCodeRequestRedirectFilter( - OAuth2LoginConfigurer.getClientRegistrationRepository(this.getBuilder())); - if (this.authorizationRequestMatcher != null) { - filter.setAuthorizationRequestMatcher(this.authorizationRequestMatcher); - } - if (this.authorizationRequestBuilder != null) { - filter.setAuthorizationUriBuilder(this.authorizationRequestBuilder); - } - http.addFilter(this.postProcess(filter)); - } - - private AuthorizationRequestUriBuilder getAuthorizationRequestBuilder() { - if (this.authorizationRequestBuilder == null) { - this.authorizationRequestBuilder = new DefaultAuthorizationRequestUriBuilder(); - } - return this.authorizationRequestBuilder; - } -} diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java index 810ddf010e..c5efaf35b4 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java @@ -18,86 +18,64 @@ package org.springframework.security.config.annotation.web.configurers.oauth2.cl import org.springframework.context.ApplicationContext; import org.springframework.core.ResolvableType; 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.AbstractAuthenticationFilterConfigurer; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationToken; +import org.springframework.security.oauth2.client.authentication.AuthorizationGrantAuthenticator; 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 org.springframework.security.oauth2.client.token.SecurityTokenRepository; import org.springframework.security.oauth2.client.user.OAuth2UserService; +import org.springframework.security.oauth2.client.web.AuthorizationCodeAuthenticationFilter; import org.springframework.security.oauth2.client.web.AuthorizationCodeRequestRedirectFilter; import org.springframework.security.oauth2.client.web.AuthorizationGrantTokenExchanger; +import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.client.web.AuthorizationRequestUriBuilder; import org.springframework.security.oauth2.core.AccessToken; import org.springframework.security.oauth2.core.user.OAuth2User; -import org.springframework.security.web.authentication.AuthenticationFailureHandler; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.security.web.util.matcher.RequestVariablesExtractor; import org.springframework.util.Assert; import java.net.URI; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import java.util.stream.Stream; import static org.springframework.security.oauth2.client.web.AuthorizationCodeRequestRedirectFilter.REGISTRATION_ID_URI_VARIABLE_NAME; /** + * A security configurer for OAuth 2.0 / OpenID Connect 1.0 login. + * * @author Joe Grandja + * @since 5.0 */ -public final class OAuth2LoginConfigurer> extends - AbstractHttpConfigurer, H> { +public final class OAuth2LoginConfigurer> extends + AbstractAuthenticationFilterConfigurer, AuthorizationCodeAuthenticationFilter> { - private final AuthorizationCodeRequestRedirectFilterConfigurer authorizationCodeRequestRedirectFilterConfigurer; - private final AuthorizationCodeAuthenticationFilterConfigurer authorizationCodeAuthenticationFilterConfigurer; - private final AuthorizationEndpointConfig authorizationEndpointConfig; - private final TokenEndpointConfig tokenEndpointConfig; - private final RedirectionEndpointConfig redirectionEndpointConfig; - private final UserInfoEndpointConfig userInfoEndpointConfig; + private final AuthorizationCodeGrantConfigurer authorizationCodeGrantConfigurer = new AuthorizationCodeGrantLoginConfigurer(); + private final AuthorizationEndpointConfig authorizationEndpointConfig = new AuthorizationEndpointConfig(); + private final TokenEndpointConfig tokenEndpointConfig = new TokenEndpointConfig(); + private final RedirectionEndpointConfig redirectionEndpointConfig = new RedirectionEndpointConfig(); + private final UserInfoEndpointConfig userInfoEndpointConfig = new UserInfoEndpointConfig(); public OAuth2LoginConfigurer() { - this.authorizationCodeRequestRedirectFilterConfigurer = new AuthorizationCodeRequestRedirectFilterConfigurer<>(); - this.authorizationCodeAuthenticationFilterConfigurer = new AuthorizationCodeAuthenticationFilterConfigurer<>(); - this.authorizationEndpointConfig = new AuthorizationEndpointConfig(); - this.tokenEndpointConfig = new TokenEndpointConfig(); - this.redirectionEndpointConfig = new RedirectionEndpointConfig(); - this.userInfoEndpointConfig = new UserInfoEndpointConfig(); + super(new AuthorizationCodeAuthenticationFilter(), null); } - public OAuth2LoginConfigurer clients(ClientRegistration... clientRegistrations) { + public OAuth2LoginConfigurer clients(ClientRegistration... clientRegistrations) { Assert.notEmpty(clientRegistrations, "clientRegistrations cannot be empty"); return this.clients(new InMemoryClientRegistrationRepository(Arrays.asList(clientRegistrations))); } - public OAuth2LoginConfigurer clients(ClientRegistrationRepository clientRegistrationRepository) { + public OAuth2LoginConfigurer clients(ClientRegistrationRepository clientRegistrationRepository) { Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); return this; } - public OAuth2LoginConfigurer userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper) { - Assert.notNull(userAuthoritiesMapper, "userAuthoritiesMapper cannot be null"); - this.authorizationCodeAuthenticationFilterConfigurer.userAuthoritiesMapper(userAuthoritiesMapper); - return this; - } - - public OAuth2LoginConfigurer successHandler(AuthenticationSuccessHandler authenticationSuccessHandler) { - Assert.notNull(authenticationSuccessHandler, "authenticationSuccessHandler cannot be null"); - this.authorizationCodeAuthenticationFilterConfigurer.successHandler(authenticationSuccessHandler); - return this; - } - - public OAuth2LoginConfigurer failureHandler(AuthenticationFailureHandler authenticationFailureHandler) { - Assert.notNull(authenticationFailureHandler, "authenticationFailureHandler cannot be null"); - this.authorizationCodeAuthenticationFilterConfigurer.failureHandler(authenticationFailureHandler); - return this; - } - public AuthorizationEndpointConfig authorizationEndpoint() { return this.authorizationEndpointConfig; } @@ -107,19 +85,25 @@ public final class OAuth2LoginConfigurer> exten private AuthorizationEndpointConfig() { } + public AuthorizationEndpointConfig requestMatcher(RequestMatcher authorizationRequestMatcher) { + Assert.notNull(authorizationRequestMatcher, "authorizationRequestMatcher cannot be null"); + authorizationCodeGrantConfigurer.authorizationRequestMatcher(authorizationRequestMatcher); + return this; + } + public AuthorizationEndpointConfig authorizationRequestBuilder(AuthorizationRequestUriBuilder authorizationRequestBuilder) { Assert.notNull(authorizationRequestBuilder, "authorizationRequestBuilder cannot be null"); - OAuth2LoginConfigurer.this.authorizationCodeRequestRedirectFilterConfigurer.authorizationRequestBuilder(authorizationRequestBuilder); + authorizationCodeGrantConfigurer.authorizationRequestBuilder(authorizationRequestBuilder); return this; } - public AuthorizationEndpointConfig requestMatcher(R authorizationRequestMatcher) { - Assert.notNull(authorizationRequestMatcher, "authorizationRequestMatcher cannot be null"); - OAuth2LoginConfigurer.this.authorizationCodeRequestRedirectFilterConfigurer.authorizationRequestMatcher(authorizationRequestMatcher); + public AuthorizationEndpointConfig authorizationRequestRepository(AuthorizationRequestRepository authorizationRequestRepository) { + Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null"); + authorizationCodeGrantConfigurer.authorizationRequestRepository(authorizationRequestRepository); return this; } - public OAuth2LoginConfigurer and() { + public OAuth2LoginConfigurer and() { return OAuth2LoginConfigurer.this; } } @@ -133,21 +117,29 @@ public final class OAuth2LoginConfigurer> exten private TokenEndpointConfig() { } + public TokenEndpointConfig authorizationCodeAuthenticator( + AuthorizationGrantAuthenticator authorizationCodeAuthenticator) { + + Assert.notNull(authorizationCodeAuthenticator, "authorizationCodeAuthenticator cannot be null"); + authorizationCodeGrantConfigurer.authorizationCodeAuthenticator(authorizationCodeAuthenticator); + return this; + } + public TokenEndpointConfig authorizationCodeTokenExchanger( AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger) { Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null"); - OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.authorizationCodeTokenExchanger(authorizationCodeTokenExchanger); + authorizationCodeGrantConfigurer.authorizationCodeTokenExchanger(authorizationCodeTokenExchanger); return this; } public TokenEndpointConfig accessTokenRepository(SecurityTokenRepository accessTokenRepository) { Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null"); - OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.accessTokenRepository(accessTokenRepository); + authorizationCodeGrantConfigurer.accessTokenRepository(accessTokenRepository); return this; } - public OAuth2LoginConfigurer and() { + public OAuth2LoginConfigurer and() { return OAuth2LoginConfigurer.this; } } @@ -161,13 +153,13 @@ public final class OAuth2LoginConfigurer> exten private RedirectionEndpointConfig() { } - public RedirectionEndpointConfig requestMatcher(R authorizationResponseMatcher) { + public RedirectionEndpointConfig requestMatcher(RequestMatcher authorizationResponseMatcher) { Assert.notNull(authorizationResponseMatcher, "authorizationResponseMatcher cannot be null"); - OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.authorizationResponseMatcher(authorizationResponseMatcher); + authorizationCodeGrantConfigurer.authorizationResponseMatcher(authorizationResponseMatcher); return this; } - public OAuth2LoginConfigurer and() { + public OAuth2LoginConfigurer and() { return OAuth2LoginConfigurer.this; } } @@ -181,73 +173,82 @@ public final class OAuth2LoginConfigurer> exten private UserInfoEndpointConfig() { } - public UserInfoEndpointConfig userInfoService(OAuth2UserService userInfoService) { - Assert.notNull(userInfoService, "userInfoService cannot be null"); - OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.userInfoService(userInfoService); + public UserInfoEndpointConfig userService(OAuth2UserService userService) { + Assert.notNull(userService, "userService cannot be null"); + authorizationCodeGrantConfigurer.userService(userService); return this; } public UserInfoEndpointConfig customUserType(Class customUserType, URI userInfoUri) { Assert.notNull(customUserType, "customUserType cannot be null"); Assert.notNull(userInfoUri, "userInfoUri cannot be null"); - OAuth2LoginConfigurer.this.authorizationCodeAuthenticationFilterConfigurer.customUserType(customUserType, userInfoUri); + authorizationCodeGrantConfigurer.customUserType(customUserType, userInfoUri); return this; } - public OAuth2LoginConfigurer and() { + public UserInfoEndpointConfig userAuthoritiesMapper(GrantedAuthoritiesMapper userAuthoritiesMapper) { + Assert.notNull(userAuthoritiesMapper, "userAuthoritiesMapper cannot be null"); + authorizationCodeGrantConfigurer.userAuthoritiesMapper(userAuthoritiesMapper); + return this; + } + + public OAuth2LoginConfigurer and() { return OAuth2LoginConfigurer.this; } } @Override - public void init(H http) throws Exception { - this.authorizationCodeRequestRedirectFilterConfigurer.setBuilder(http); - this.authorizationCodeAuthenticationFilterConfigurer.setBuilder(http); - - this.authorizationCodeRequestRedirectFilterConfigurer.init(http); - this.authorizationCodeAuthenticationFilterConfigurer.init(http); + public void init(B http) throws Exception { + super.init(http); + this.authorizationCodeGrantConfigurer.setBuilder(http); + this.authorizationCodeGrantConfigurer.init(http); this.initDefaultLoginFilter(http); } @Override - public void configure(H http) throws Exception { - this.authorizationCodeRequestRedirectFilterConfigurer.configure(http); - this.authorizationCodeAuthenticationFilterConfigurer.configure(http); + public void configure(B http) throws Exception { + this.authorizationCodeGrantConfigurer.configure(http); + super.configure(http); } - static > ClientRegistrationRepository getClientRegistrationRepository(H http) { - ClientRegistrationRepository clientRegistrationRepository = http.getSharedObject(ClientRegistrationRepository.class); + @Override + protected RequestMatcher createLoginProcessingUrlMatcher(String loginProcessingUrl) { + return (this.authorizationCodeGrantConfigurer.getAuthorizationResponseMatcher() != null ? + this.authorizationCodeGrantConfigurer.getAuthorizationResponseMatcher() : + this.getAuthenticationFilter().getAuthorizationResponseMatcher()); + } + + private ClientRegistrationRepository getClientRegistrationRepository() { + ClientRegistrationRepository clientRegistrationRepository = this.getBuilder().getSharedObject(ClientRegistrationRepository.class); if (clientRegistrationRepository == null) { - clientRegistrationRepository = getDefaultClientRegistrationRepository(http); - http.setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); + clientRegistrationRepository = this.getClientRegistrationRepositoryBean(); + this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); } return clientRegistrationRepository; } - private static > ClientRegistrationRepository getDefaultClientRegistrationRepository(H http) { - return http.getSharedObject(ApplicationContext.class).getBean(ClientRegistrationRepository.class); + private ClientRegistrationRepository getClientRegistrationRepositoryBean() { + return this.getBuilder().getSharedObject(ApplicationContext.class).getBean(ClientRegistrationRepository.class); } - private void initDefaultLoginFilter(H http) { + private void initDefaultLoginFilter(B http) { DefaultLoginPageGeneratingFilter loginPageGeneratingFilter = http.getSharedObject(DefaultLoginPageGeneratingFilter.class); - if (loginPageGeneratingFilter == null || this.authorizationCodeAuthenticationFilterConfigurer.isCustomLoginPage()) { + if (loginPageGeneratingFilter == null || this.isCustomLoginPage()) { return; } Iterable clientRegistrations = null; - ClientRegistrationRepository clientRegistrationRepository = getClientRegistrationRepository(http); + ClientRegistrationRepository clientRegistrationRepository = this.getClientRegistrationRepository(); ResolvableType type = ResolvableType.forInstance(clientRegistrationRepository).as(Iterable.class); - if (type != ResolvableType.NONE) { - if (Stream.of(type.resolveGenerics()).anyMatch(ClientRegistration.class::isAssignableFrom)) { - clientRegistrations = (Iterable) clientRegistrationRepository; - } + if (type != ResolvableType.NONE && ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) { + clientRegistrations = (Iterable) clientRegistrationRepository; } if (clientRegistrations == null) { return; } String authorizationRequestBaseUri; - RequestMatcher authorizationRequestMatcher = OAuth2LoginConfigurer.this.authorizationCodeRequestRedirectFilterConfigurer.getAuthorizationRequestMatcher(); + RequestMatcher authorizationRequestMatcher = authorizationCodeGrantConfigurer.getAuthorizationRequestMatcher(); if (authorizationRequestMatcher != null && AntPathRequestMatcher.class.isAssignableFrom(authorizationRequestMatcher.getClass())) { String authorizationRequestPattern = ((AntPathRequestMatcher)authorizationRequestMatcher).getPattern(); String registrationIdTemplateVariable = "{" + REGISTRATION_ID_URI_VARIABLE_NAME + "}"; @@ -261,12 +262,31 @@ public final class OAuth2LoginConfigurer> exten authorizationRequestBaseUri = AuthorizationCodeRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI; } - Map oauth2AuthenticationUrlToClientName = new HashMap<>(); - clientRegistrations.forEach(registration -> oauth2AuthenticationUrlToClientName.put( + Map authenticationUrlToClientName = new HashMap<>(); + clientRegistrations.forEach(registration -> authenticationUrlToClientName.put( authorizationRequestBaseUri + "/" + registration.getRegistrationId(), registration.getClientName())); loginPageGeneratingFilter.setOauth2LoginEnabled(true); - loginPageGeneratingFilter.setOauth2AuthenticationUrlToClientName(oauth2AuthenticationUrlToClientName); - loginPageGeneratingFilter.setLoginPageUrl(this.authorizationCodeAuthenticationFilterConfigurer.getLoginUrl()); - loginPageGeneratingFilter.setFailureUrl(this.authorizationCodeAuthenticationFilterConfigurer.getLoginFailureUrl()); + loginPageGeneratingFilter.setOauth2AuthenticationUrlToClientName(authenticationUrlToClientName); + loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage()); + loginPageGeneratingFilter.setFailureUrl(this.getFailureUrl()); + } + + private class AuthorizationCodeGrantLoginConfigurer extends AuthorizationCodeGrantConfigurer { + + @Override + public void configure(B http) throws Exception { + http.addFilter(OAuth2LoginConfigurer.this.postProcess(this.getAuthorizationRequestFilter())); + + AuthorizationCodeAuthenticationFilter authorizationResponseFilter = getAuthenticationFilter(); + authorizationResponseFilter.setClientRegistrationRepository(getClientRegistrationRepository()); + if (authorizationCodeGrantConfigurer.getAuthorizationResponseMatcher() != null) { + authorizationResponseFilter.setAuthorizationResponseMatcher( + authorizationCodeGrantConfigurer.getAuthorizationResponseMatcher()); + } + if (authorizationCodeGrantConfigurer.getAuthorizationRequestRepository() != null) { + authorizationResponseFilter.setAuthorizationRequestRepository( + authorizationCodeGrantConfigurer.getAuthorizationRequestRepository()); + } + } } } diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java index dec4ad0266..34f9dec58e 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/AuthorizationCodeRequestRedirectFilter.java @@ -77,8 +77,10 @@ public class AuthorizationCodeRequestRedirectFilter extends OncePerRequestFilter this.clientRegistrationRepository = clientRegistrationRepository; } - public final void setAuthorizationRequestMatcher(T authorizationRequestMatcher) { + public final void setAuthorizationRequestMatcher(RequestMatcher authorizationRequestMatcher) { Assert.notNull(authorizationRequestMatcher, "authorizationRequestMatcher cannot be null"); + Assert.isInstanceOf(RequestVariablesExtractor.class, authorizationRequestMatcher, + "authorizationRequestMatcher must also be a " + RequestVariablesExtractor.class.getName()); this.authorizationRequestMatcher = authorizationRequestMatcher; } diff --git a/samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java b/samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java index 05e4f66140..16b4fe11fd 100644 --- a/samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java +++ b/samples/boot/oauth2login/src/integration-test/java/org/springframework/security/samples/OAuth2LoginApplicationTests.java @@ -351,7 +351,7 @@ public class OAuth2LoginApplicationTests { .authorizationCodeTokenExchanger(this.mockAuthorizationCodeTokenExchanger()) .and() .userInfoEndpoint() - .userInfoService(this.mockUserInfoService()); + .userService(this.mockUserInfoService()); } // @formatter:on