赞
踩
参照官方文档:https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_simple
引入的项目依赖:
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.1.4.RELEASE</version>
- <relativePath />
- </parent>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.security.oauth.boot</groupId>
- <artifactId>spring-security-oauth2-autoconfigure</artifactId>
- <version>2.1.4.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.webjars</groupId>
- <artifactId>jquery</artifactId>
- <version>2.1.1</version>
- </dependency>
- <dependency>
- <groupId>org.webjars</groupId>
- <artifactId>bootstrap</artifactId>
- <version>3.2.0</version>
- </dependency>
- <dependency>
- <groupId>org.webjars</groupId>
- <artifactId>webjars-locator-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
- </dependency>
- </dependencies>
问题出现:引入一下代码,启动程序报错:The bean 'oauth2ClientFilterRegistration', defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2RestOperationsConfiguration$SessionScopedConfiguration.class], could not be registered. A bean with that name has already been defined in com.hegret.SocialApplication and overriding is disabled.
- @Bean
- public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(OAuth2ClientContextFilter filter) {
- FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<OAuth2ClientContextFilter>();
- registration.setFilter(filter);
- registration.setOrder(-100);
- return registration;
- }
-
- . ____ _ __ _ _
- /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
- ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
- \\/ ___)| |_)| | | | | || (_| | ) ) ) )
- ' |____| .__|_| |_|_| |_\__, | / / / /
- =========|_|==============|___/=/_/_/_/
- :: Spring Boot :: (v2.1.4.RELEASE)
-
- 2019-06-05 14:42:20.603 INFO 8560 --- [ main] com.hegret.SocialApplication : Starting SocialApplication on zsx with PID 8560 (F:\workspace-test\spring-oauth2-server\target\classes started by zhang in F:\workspace-test\spring-oauth2-server)
- 2019-06-05 14:42:20.605 INFO 8560 --- [ main] com.hegret.SocialApplication : No active profile set, falling back to default profiles: default
- 2019-06-05 14:42:20.877 WARN 8560 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'oauth2ClientFilterRegistration' defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2RestOperationsConfiguration$SessionScopedConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2RestOperationsConfiguration$SessionScopedConfiguration; factoryMethodName=oauth2ClientFilterRegistration; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2RestOperationsConfiguration$SessionScopedConfiguration.class]] for bean 'oauth2ClientFilterRegistration': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=socialApplication; factoryMethodName=oauth2ClientFilterRegistration; initMethodName=null; destroyMethodName=(inferred); defined in com.hegret.SocialApplication] bound.
- 2019-06-05 14:42:20.883 INFO 8560 --- [ main] ConditionEvaluationReportLoggingListener :
-
- Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
- 2019-06-05 14:42:20.884 ERROR 8560 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
-
- ***************************
- APPLICATION FAILED TO START
- ***************************
-
- Description:
-
- The bean 'oauth2ClientFilterRegistration', defined in class path resource [org/springframework/boot/autoconfigure/security/oauth2/client/OAuth2RestOperationsConfiguration$SessionScopedConfiguration.class], could not be registered. A bean with that name has already been defined in com.hegret.SocialApplication and overriding is disabled.
-
- Action:
-
- Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
-
问题分析:跟踪源码,在OAuth2RestOperationsConfiguration类中已经定义过该bean对象了
- /*
- * 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
- *
- * https://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.boot.autoconfigure.security.oauth2.client;
-
- import org.springframework.beans.factory.ObjectProvider;
- import org.springframework.beans.factory.annotation.Qualifier;
- import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
- import org.springframework.boot.autoconfigure.condition.ConditionMessage;
- import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
- import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
- import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
- import org.springframework.boot.autoconfigure.security.SecurityProperties;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.boot.web.servlet.FilterRegistrationBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.ConditionContext;
- import org.springframework.context.annotation.Conditional;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Import;
- import org.springframework.context.annotation.Primary;
- import org.springframework.context.annotation.Scope;
- import org.springframework.context.annotation.ScopedProxyMode;
- import org.springframework.core.type.AnnotatedTypeMetadata;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.context.SecurityContextHolder;
- import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
- import org.springframework.security.oauth2.client.OAuth2ClientContext;
- import org.springframework.security.oauth2.client.filter.OAuth2ClientContextFilter;
- import org.springframework.security.oauth2.client.token.AccessTokenRequest;
- import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
- import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
- import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
- import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
- import org.springframework.security.oauth2.config.annotation.web.configuration.OAuth2ClientConfiguration;
- import org.springframework.security.oauth2.provider.OAuth2Authentication;
- import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
- import org.springframework.util.StringUtils;
-
- /**
- * Configuration for OAuth2 Single Sign On REST operations.
- *
- * @author Dave Syer
- * @author Madhura Bhave
- * @since 1.3.0
- */
- @Configuration
- @ConditionalOnClass(EnableOAuth2Client.class)
- public class OAuth2RestOperationsConfiguration {
-
- @Configuration
- @Conditional(ClientCredentialsCondition.class)
- protected static class SingletonScopedConfiguration {
-
- @Bean
- @ConfigurationProperties(prefix = "security.oauth2.client")
- @Primary
- public ClientCredentialsResourceDetails oauth2RemoteResource() {
- ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
- return details;
- }
-
- @Bean
- public DefaultOAuth2ClientContext oauth2ClientContext() {
- return new DefaultOAuth2ClientContext(new DefaultAccessTokenRequest());
- }
-
- }
-
- @Configuration
- @ConditionalOnBean(OAuth2ClientConfiguration.class)
- @Conditional({ OAuth2ClientIdCondition.class, NoClientCredentialsCondition.class })
- @Import(OAuth2ProtectedResourceDetailsConfiguration.class)
- protected static class SessionScopedConfiguration {
-
- @Bean
- public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(
- OAuth2ClientContextFilter filter, SecurityProperties security) {
- FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<>();
- registration.setFilter(filter);
- registration.setOrder(security.getFilter().getOrder() - 10);
- return registration;
- }
-
- }
-
- // When the authentication is per cookie but the stored token is an oauth2 one, we can
- // pass that on to a client that wants to call downstream. We don't even need an
- // OAuth2ClientContextFilter until we need to refresh the access token. To handle
- // refresh tokens you need to @EnableOAuth2Client
- @Configuration
- @ConditionalOnMissingBean(OAuth2ClientConfiguration.class)
- @Conditional({ OAuth2ClientIdCondition.class, NoClientCredentialsCondition.class })
- @Import(OAuth2ProtectedResourceDetailsConfiguration.class)
- protected static class RequestScopedConfiguration {
-
- @Bean
- @Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
- public DefaultOAuth2ClientContext oauth2ClientContext() {
- DefaultOAuth2ClientContext context = new DefaultOAuth2ClientContext(
- new DefaultAccessTokenRequest());
- Authentication principal = SecurityContextHolder.getContext()
- .getAuthentication();
- if (principal instanceof OAuth2Authentication) {
- OAuth2Authentication authentication = (OAuth2Authentication) principal;
- Object details = authentication.getDetails();
- if (details instanceof OAuth2AuthenticationDetails) {
- OAuth2AuthenticationDetails oauthsDetails = (OAuth2AuthenticationDetails) details;
- String token = oauthsDetails.getTokenValue();
- context.setAccessToken(new DefaultOAuth2AccessToken(token));
- }
- }
- return context;
- }
-
- }
-
- /**
- * Condition to check if a {@code security.oauth2.client.client-id} is specified.
- */
- static class OAuth2ClientIdCondition extends SpringBootCondition {
-
- @Override
- public ConditionOutcome getMatchOutcome(ConditionContext context,
- AnnotatedTypeMetadata metadata) {
- String clientId = context.getEnvironment()
- .getProperty("security.oauth2.client.client-id");
- ConditionMessage.Builder message = ConditionMessage
- .forCondition("OAuth Client ID");
- if (StringUtils.hasLength(clientId)) {
- return ConditionOutcome.match(message
- .foundExactly("security.oauth2.client.client-id property"));
- }
- return ConditionOutcome.noMatch(message
- .didNotFind("security.oauth2.client.client-id property").atAll());
- }
-
- }
-
- /**
- * Condition to check for no client credentials.
- */
- static class NoClientCredentialsCondition extends NoneNestedConditions {
-
- NoClientCredentialsCondition() {
- super(ConfigurationPhase.PARSE_CONFIGURATION);
- }
-
- @Conditional(ClientCredentialsCondition.class)
- static class ClientCredentialsActivated {
- }
-
- }
-
- /**
- * Condition to check for client credentials.
- */
- static class ClientCredentialsCondition extends AnyNestedCondition {
-
- ClientCredentialsCondition() {
- super(ConfigurationPhase.PARSE_CONFIGURATION);
- }
-
- @ConditionalOnProperty(prefix = "security.oauth2.client", name = "grant-type", havingValue = "client_credentials", matchIfMissing = false)
- static class ClientCredentialsConfigured {
- }
-
- @ConditionalOnNotWebApplication
- static class NoWebApplication {
- }
-
- }
-
- }
解决方法:
在application.yml文件中添加配置,对bean进行重新定义覆盖
- spring:
- main:
- allow-bean-definition-overriding: true
重新启动,运行正常
-
- . ____ _ __ _ _
- /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
- ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
- \\/ ___)| |_)| | | | | || (_| | ) ) ) )
- ' |____| .__|_| |_|_| |_\__, | / / / /
- =========|_|==============|___/=/_/_/_/
- :: Spring Boot :: (v2.1.4.RELEASE)
-
- 2019-06-05 15:34:51.519 INFO 724 --- [ main] com.hegret.SocialApplication : Starting SocialApplication on zsx with PID 724 (F:\workspace-test\spring-oauth2-server\target\classes started by zhang in F:\workspace-test\spring-oauth2-server)
- 2019-06-05 15:34:51.521 INFO 724 --- [ main] com.hegret.SocialApplication : No active profile set, falling back to default profiles: default
- 2019-06-05 15:34:52.069 INFO 724 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
- 2019-06-05 15:34:52.081 INFO 724 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
- 2019-06-05 15:34:52.081 INFO 724 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.17]
- 2019-06-05 15:34:52.147 INFO 724 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
- 2019-06-05 15:34:52.147 INFO 724 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 606 ms
- 2019-06-05 15:34:52.312 INFO 724 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
- 2019-06-05 15:34:52.358 INFO 724 --- [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html]
- 2019-06-05 15:34:52.398 INFO 724 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :
-
- Using generated security password: d8670419-1986-4c55-a811-e147c18f0174
-
- 2019-06-05 15:34:52.444 INFO 724 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Creating filter chain: Ant [pattern='/**'], [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@1cb19dba, org.springframework.security.web.context.SecurityContextPersistenceFilter@6e106680, org.springframework.security.web.header.HeaderWriterFilter@16c8b7bd, org.springframework.security.web.csrf.CsrfFilter@4dafba3e, org.springframework.security.web.authentication.logout.LogoutFilter@2f5c1332, org.springframework.security.oauth2.client.filter.OAuth2ClientAuthenticationProcessingFilter@7c3ebc6b, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@55ecbafe, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@205b132e, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1931d99, org.springframework.security.web.session.SessionManagementFilter@65bcf7c2, org.springframework.security.web.access.ExceptionTranslationFilter@476a736d, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@5bca7664]
- 2019-06-05 15:34:52.479 INFO 724 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
- 2019-06-05 15:34:52.481 INFO 724 --- [ main] com.hegret.SocialApplication : Started SocialApplication in 1.146 seconds (JVM running for 1.472)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。