瀏覽代碼

Favor ObjectProvider

Closes gh-15805
Tran Ngoc Nhan 11 月之前
父節點
當前提交
e618fc425d
共有 24 個文件被更改,包括 106 次插入231 次删除
  1. 5 17
      config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfiguration.java
  2. 2 5
      config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java
  3. 10 15
      config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java
  4. 4 6
      config/src/main/java/org/springframework/security/config/annotation/rsocket/RSocketSecurity.java
  5. 2 6
      config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java
  6. 4 16
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.java
  7. 10 21
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationConfigurer.java
  8. 3 11
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java
  9. 4 8
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java
  10. 5 7
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java
  11. 4 8
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java
  12. 3 12
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/X509Configurer.java
  13. 4 6
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2ClientConfigurer.java
  14. 9 12
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java
  15. 5 6
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcLogoutConfigurer.java
  16. 2 7
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurer.java
  17. 2 8
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurer.java
  18. 2 4
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LogoutConfigurer.java
  19. 2 5
      config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2MetadataConfigurer.java
  20. 4 12
      config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java
  21. 4 8
      config/src/main/java/org/springframework/security/config/http/GrantedAuthorityDefaultsParserUtils.java
  22. 4 8
      config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java
  23. 8 15
      config/src/main/java/org/springframework/security/config/method/MethodSecurityBeanDefinitionParser.java
  24. 4 8
      config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java

+ 5 - 17
config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/AuthenticationConfiguration.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -28,7 +28,6 @@ import org.apache.commons.logging.LogFactory;
 import org.springframework.aop.framework.ProxyFactoryBean;
 import org.springframework.aop.target.LazyInitTargetSource;
 import org.springframework.beans.factory.BeanFactoryUtils;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ConfigurableApplicationContext;
@@ -57,6 +56,7 @@ import org.springframework.util.Assert;
  * Exports the authentication {@link Configuration}
  *
  * @author Rob Winch
+ * @author Ngoc Nhan
  * @since 3.2
  *
  */
@@ -197,15 +197,6 @@ public class AuthenticationConfiguration {
 		return lazyBean(AuthenticationManager.class);
 	}
 
-	private static <T> T getBeanOrNull(ApplicationContext applicationContext, Class<T> type) {
-		try {
-			return applicationContext.getBean(type);
-		}
-		catch (NoSuchBeanDefinitionException notFound) {
-			return null;
-		}
-	}
-
 	private static class EnableGlobalAuthenticationAutowiredConfigurer extends GlobalAuthenticationConfigurerAdapter {
 
 		private final ApplicationContext context;
@@ -330,12 +321,9 @@ public class AuthenticationConfiguration {
 			if (this.passwordEncoder != null) {
 				return this.passwordEncoder;
 			}
-			PasswordEncoder passwordEncoder = getBeanOrNull(this.applicationContext, PasswordEncoder.class);
-			if (passwordEncoder == null) {
-				passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
-			}
-			this.passwordEncoder = passwordEncoder;
-			return passwordEncoder;
+			this.passwordEncoder = this.applicationContext.getBeanProvider(PasswordEncoder.class)
+				.getIfUnique(PasswordEncoderFactories::createDelegatingPasswordEncoder);
+			return this.passwordEncoder;
 		}
 
 		@Override

+ 2 - 5
config/src/main/java/org/springframework/security/config/annotation/authentication/configuration/InitializeUserDetailsBeanManagerConfigurer.java

@@ -39,6 +39,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
  * {@link PasswordEncoder} is defined will wire this up too.
  *
  * @author Rob Winch
+ * @author Ngoc Nhan
  * @since 4.1
  */
 @Order(InitializeUserDetailsBeanManagerConfigurer.DEFAULT_ORDER)
@@ -121,11 +122,7 @@ class InitializeUserDetailsBeanManagerConfigurer extends GlobalAuthenticationCon
 		 * component, null otherwise.
 		 */
 		private <T> T getBeanOrNull(Class<T> type) {
-			String[] beanNames = InitializeUserDetailsBeanManagerConfigurer.this.context.getBeanNamesForType(type);
-			if (beanNames.length != 1) {
-				return null;
-			}
-			return InitializeUserDetailsBeanManagerConfigurer.this.context.getBean(beanNames[0], type);
+			return InitializeUserDetailsBeanManagerConfigurer.this.context.getBeanProvider(type).getIfUnique();
 		}
 
 		/**

+ 10 - 15
config/src/main/java/org/springframework/security/config/annotation/method/configuration/GlobalMethodSecurityConfiguration.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -27,7 +27,6 @@ import org.apache.commons.logging.LogFactory;
 import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.BeanFactory;
 import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.beans.factory.SmartInitializingSingleton;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.BeanDefinition;
@@ -84,6 +83,7 @@ import org.springframework.util.Assert;
  *
  * @author Rob Winch
  * @author Eddú Meléndez
+ * @author Ngoc Nhan
  * @since 3.2
  * @see EnableGlobalMethodSecurity
  * @deprecated Use {@link PrePostMethodSecurityConfiguration},
@@ -168,19 +168,19 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
 		catch (Exception ex) {
 			throw new RuntimeException(ex);
 		}
-		PermissionEvaluator permissionEvaluator = getSingleBeanOrNull(PermissionEvaluator.class);
+		PermissionEvaluator permissionEvaluator = getBeanOrNull(PermissionEvaluator.class);
 		if (permissionEvaluator != null) {
 			this.defaultMethodExpressionHandler.setPermissionEvaluator(permissionEvaluator);
 		}
-		RoleHierarchy roleHierarchy = getSingleBeanOrNull(RoleHierarchy.class);
+		RoleHierarchy roleHierarchy = getBeanOrNull(RoleHierarchy.class);
 		if (roleHierarchy != null) {
 			this.defaultMethodExpressionHandler.setRoleHierarchy(roleHierarchy);
 		}
-		AuthenticationTrustResolver trustResolver = getSingleBeanOrNull(AuthenticationTrustResolver.class);
+		AuthenticationTrustResolver trustResolver = getBeanOrNull(AuthenticationTrustResolver.class);
 		if (trustResolver != null) {
 			this.defaultMethodExpressionHandler.setTrustResolver(trustResolver);
 		}
-		GrantedAuthorityDefaults grantedAuthorityDefaults = getSingleBeanOrNull(GrantedAuthorityDefaults.class);
+		GrantedAuthorityDefaults grantedAuthorityDefaults = getBeanOrNull(GrantedAuthorityDefaults.class);
 		if (grantedAuthorityDefaults != null) {
 			this.defaultMethodExpressionHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
 		}
@@ -188,13 +188,8 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
 		this.defaultMethodExpressionHandler = this.objectPostProcessor.postProcess(this.defaultMethodExpressionHandler);
 	}
 
-	private <T> T getSingleBeanOrNull(Class<T> type) {
-		try {
-			return this.context.getBean(type);
-		}
-		catch (NoSuchBeanDefinitionException ex) {
-		}
-		return null;
+	private <T> T getBeanOrNull(Class<T> type) {
+		return this.context.getBeanProvider(type).getIfUnique();
 	}
 
 	private void initializeMethodSecurityInterceptor() throws Exception {
@@ -262,7 +257,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
 			decisionVoters.add(new Jsr250Voter());
 		}
 		RoleVoter roleVoter = new RoleVoter();
-		GrantedAuthorityDefaults grantedAuthorityDefaults = getSingleBeanOrNull(GrantedAuthorityDefaults.class);
+		GrantedAuthorityDefaults grantedAuthorityDefaults = getBeanOrNull(GrantedAuthorityDefaults.class);
 		if (grantedAuthorityDefaults != null) {
 			roleVoter.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
 		}
@@ -373,7 +368,7 @@ public class GlobalMethodSecurityConfiguration implements ImportAware, SmartInit
 			sources.add(new SecuredAnnotationSecurityMetadataSource());
 		}
 		if (isJsr250Enabled) {
-			GrantedAuthorityDefaults grantedAuthorityDefaults = getSingleBeanOrNull(GrantedAuthorityDefaults.class);
+			GrantedAuthorityDefaults grantedAuthorityDefaults = getBeanOrNull(GrantedAuthorityDefaults.class);
 			Jsr250MethodSecurityMetadataSource jsr250MethodSecurityMetadataSource = this.context
 				.getBean(Jsr250MethodSecurityMetadataSource.class);
 			if (grantedAuthorityDefaults != null) {

+ 4 - 6
config/src/main/java/org/springframework/security/config/annotation/rsocket/RSocketSecurity.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2021 the original author or authors.
+ * Copyright 2019-2024 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.
@@ -108,6 +108,7 @@ import org.springframework.security.rsocket.util.matcher.RoutePayloadExchangeMat
  * @author Luis Felipe Vega
  * @author Manuel Tejeda
  * @author Ebert Toribio
+ * @author Ngoc Nhan
  * @since 5.2
  */
 public class RSocketSecurity {
@@ -238,15 +239,12 @@ public class RSocketSecurity {
 		return getBeanOrNull(ResolvableType.forClass(beanClass));
 	}
 
+	@SuppressWarnings("unchecked")
 	private <T> T getBeanOrNull(ResolvableType type) {
 		if (this.context == null) {
 			return null;
 		}
-		String[] names = this.context.getBeanNamesForType(type);
-		if (names.length == 1) {
-			return (T) this.context.getBean(names[0]);
-		}
-		return null;
+		return (T) this.context.getBeanProvider(type).getIfUnique();
 	}
 
 	protected void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

+ 2 - 6
config/src/main/java/org/springframework/security/config/annotation/web/builders/HttpSecurity.java

@@ -139,6 +139,7 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
  *
  * @author Rob Winch
  * @author Joe Grandja
+ * @author Ngoc Nhan
  * @since 3.2
  * @see EnableWebSecurity
  */
@@ -3721,12 +3722,7 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
 	}
 
 	private ObservationRegistry getObservationRegistry() {
-		ApplicationContext context = getContext();
-		String[] names = context.getBeanNamesForType(ObservationRegistry.class);
-		if (names.length == 1) {
-			return (ObservationRegistry) context.getBean(names[0]);
-		}
-		return ObservationRegistry.NOOP;
+		return getContext().getBeanProvider(ObservationRegistry.class).getIfUnique(() -> ObservationRegistry.NOOP);
 	}
 
 	/**

+ 4 - 16
config/src/main/java/org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.java

@@ -20,7 +20,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
@@ -56,6 +55,7 @@ import static org.springframework.security.config.Customizer.withDefaults;
  *
  * @author Eleftheria Stein
  * @author Jinwoo Bae
+ * @author Ngoc Nhan
  * @since 5.4
  */
 @Configuration(proxyBeanMethods = false)
@@ -226,21 +226,9 @@ class HttpSecurityConfiguration {
 			if (this.passwordEncoder != null) {
 				return this.passwordEncoder;
 			}
-			PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
-			if (passwordEncoder == null) {
-				passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
-			}
-			this.passwordEncoder = passwordEncoder;
-			return passwordEncoder;
-		}
-
-		private <T> T getBeanOrNull(Class<T> type) {
-			try {
-				return this.applicationContext.getBean(type);
-			}
-			catch (NoSuchBeanDefinitionException ex) {
-				return null;
-			}
+			this.passwordEncoder = this.applicationContext.getBeanProvider(PasswordEncoder.class)
+				.getIfUnique(PasswordEncoderFactories::createDelegatingPasswordEncoder);
+			return this.passwordEncoder;
 		}
 
 		@Override

+ 10 - 21
config/src/main/java/org/springframework/security/config/annotation/web/configurers/ExpressionUrlAuthorizationConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -75,6 +75,7 @@ import org.springframework.util.StringUtils;
  * @param <H> the type of {@link HttpSecurityBuilder} that is being configured
  * @author Rob Winch
  * @author Yanming Zhou
+ * @author Ngoc Nhan
  * @since 3.2
  * @see org.springframework.security.config.annotation.web.builders.HttpSecurity#authorizeRequests()
  * @deprecated Use {@link AuthorizeHttpRequestsConfigurer} instead
@@ -106,10 +107,9 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
 	 * @see HttpSecurity#authorizeRequests()
 	 */
 	public ExpressionUrlAuthorizationConfigurer(ApplicationContext context) {
-		String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
-		if (grantedAuthorityDefaultsBeanNames.length == 1) {
-			GrantedAuthorityDefaults grantedAuthorityDefaults = context.getBean(grantedAuthorityDefaultsBeanNames[0],
-					GrantedAuthorityDefaults.class);
+		GrantedAuthorityDefaults grantedAuthorityDefaults = context.getBeanProvider(GrantedAuthorityDefaults.class)
+			.getIfUnique();
+		if (grantedAuthorityDefaults != null) {
 			this.rolePrefix = grantedAuthorityDefaults.getRolePrefix();
 		}
 		else {
@@ -167,22 +167,11 @@ public final class ExpressionUrlAuthorizationConfigurer<H extends HttpSecurityBu
 		}
 		ApplicationContext context = http.getSharedObject(ApplicationContext.class);
 		if (context != null) {
-			String[] roleHiearchyBeanNames = context.getBeanNamesForType(RoleHierarchy.class);
-			if (roleHiearchyBeanNames.length == 1) {
-				defaultHandler.setRoleHierarchy(context.getBean(roleHiearchyBeanNames[0], RoleHierarchy.class));
-			}
-			String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
-			if (grantedAuthorityDefaultsBeanNames.length == 1) {
-				GrantedAuthorityDefaults grantedAuthorityDefaults = context
-					.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
-				defaultHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
-			}
-			String[] permissionEvaluatorBeanNames = context.getBeanNamesForType(PermissionEvaluator.class);
-			if (permissionEvaluatorBeanNames.length == 1) {
-				PermissionEvaluator permissionEvaluator = context.getBean(permissionEvaluatorBeanNames[0],
-						PermissionEvaluator.class);
-				defaultHandler.setPermissionEvaluator(permissionEvaluator);
-			}
+			context.getBeanProvider(RoleHierarchy.class).ifUnique(defaultHandler::setRoleHierarchy);
+			context.getBeanProvider(GrantedAuthorityDefaults.class)
+				.ifUnique((grantedAuthorityDefaults) -> defaultHandler
+					.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix()));
+			context.getBeanProvider(PermissionEvaluator.class).ifUnique(defaultHandler::setPermissionEvaluator);
 		}
 		this.expressionHandler = postProcess(defaultHandler);
 		return this.expressionHandler;

+ 3 - 11
config/src/main/java/org/springframework/security/config/annotation/web/configurers/RememberMeConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configurers;
 
 import java.util.UUID;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.RememberMeAuthenticationProvider;
@@ -78,6 +77,7 @@ import org.springframework.util.Assert;
  *
  * @author Rob Winch
  * @author Eddú Meléndez
+ * @author Ngoc Nhan
  * @since 3.2
  */
 public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
@@ -444,20 +444,12 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
 		if (shared != null) {
 			return shared;
 		}
-		return getBeanOrNull(type);
-	}
 
-	private <T> T getBeanOrNull(Class<T> type) {
 		ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
 		if (context == null) {
 			return null;
 		}
-		try {
-			return context.getBean(type);
-		}
-		catch (NoSuchBeanDefinitionException ex) {
-			return null;
-		}
+		return context.getBeanProvider(type).getIfUnique();
 	}
 
 }

+ 4 - 8
config/src/main/java/org/springframework/security/config/annotation/web/configurers/RequestCacheConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -20,7 +20,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.http.MediaType;
 import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
@@ -67,6 +66,7 @@ import org.springframework.web.accept.HeaderContentNegotiationStrategy;
  * </ul>
  *
  * @author Rob Winch
+ * @author Ngoc Nhan
  * @since 3.2
  * @see RequestCache
  */
@@ -134,12 +134,8 @@ public final class RequestCacheConfigurer<H extends HttpSecurityBuilder<H>>
 		if (context == null) {
 			return null;
 		}
-		try {
-			return context.getBean(type);
-		}
-		catch (NoSuchBeanDefinitionException ex) {
-			return null;
-		}
+
+		return context.getBeanProvider(type).getIfUnique();
 	}
 
 	@SuppressWarnings("unchecked")

+ 5 - 7
config/src/main/java/org/springframework/security/config/annotation/web/configurers/ServletApiConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -56,6 +56,7 @@ import org.springframework.security.web.servletapi.SecurityContextHolderAwareReq
  * </ul>
  *
  * @author Rob Winch
+ * @author Ngoc Nhan
  * @since 3.2
  */
 public final class ServletApiConfigurer<H extends HttpSecurityBuilder<H>>
@@ -92,12 +93,9 @@ public final class ServletApiConfigurer<H extends HttpSecurityBuilder<H>>
 		}
 		ApplicationContext context = http.getSharedObject(ApplicationContext.class);
 		if (context != null) {
-			String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
-			if (grantedAuthorityDefaultsBeanNames.length == 1) {
-				GrantedAuthorityDefaults grantedAuthorityDefaults = context
-					.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
-				this.securityContextRequestFilter.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
-			}
+			context.getBeanProvider(GrantedAuthorityDefaults.class)
+				.ifUnique((grantedAuthorityDefaults) -> this.securityContextRequestFilter
+					.setRolePrefix(grantedAuthorityDefaults.getRolePrefix()));
 			this.securityContextRequestFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy());
 		}
 		this.securityContextRequestFilter = postProcess(this.securityContextRequestFilter);

+ 4 - 8
config/src/main/java/org/springframework/security/config/annotation/web/configurers/SessionManagementConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -25,7 +25,6 @@ import java.util.Set;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.GenericApplicationListenerAdapter;
@@ -100,6 +99,7 @@ import org.springframework.util.CollectionUtils;
  *
  * @author Rob Winch
  * @author Onur Kagan Ozcan
+ * @author Ngoc Nhan
  * @since 3.2
  * @see SessionManagementFilter
  * @see ConcurrentSessionFilter
@@ -630,12 +630,8 @@ public final class SessionManagementConfigurer<H extends HttpSecurityBuilder<H>>
 		if (context == null) {
 			return null;
 		}
-		try {
-			return context.getBean(type);
-		}
-		catch (NoSuchBeanDefinitionException ex) {
-			return null;
-		}
+
+		return context.getBeanProvider(type).getIfUnique();
 	}
 
 	/**

+ 3 - 12
config/src/main/java/org/springframework/security/config/annotation/web/configurers/X509Configurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -18,7 +18,6 @@ package org.springframework.security.config.annotation.web.configurers;
 
 import jakarta.servlet.http.HttpServletRequest;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.security.authentication.AuthenticationDetailsSource;
 import org.springframework.security.authentication.AuthenticationManager;
@@ -74,6 +73,7 @@ import org.springframework.security.web.context.RequestAttributeSecurityContextR
  * </ul>
  *
  * @author Rob Winch
+ * @author Ngoc Nhan
  * @since 3.2
  */
 public final class X509Configurer<H extends HttpSecurityBuilder<H>>
@@ -214,20 +214,11 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
 		if (shared != null) {
 			return shared;
 		}
-		return getBeanOrNull(type);
-	}
-
-	private <T> T getBeanOrNull(Class<T> type) {
 		ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
 		if (context == null) {
 			return null;
 		}
-		try {
-			return context.getBean(type);
-		}
-		catch (NoSuchBeanDefinitionException ex) {
-			return null;
-		}
+		return context.getBeanProvider(type).getIfUnique();
 	}
 
 }

+ 4 - 6
config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2ClientConfigurer.java

@@ -86,6 +86,7 @@ import org.springframework.util.Assert;
  *
  * @author Joe Grandja
  * @author Parikshit Dutta
+ * @author Ngoc Nhan
  * @since 5.1
  * @see OAuth2AuthorizationRequestRedirectFilter
  * @see OAuth2AuthorizationCodeGrantFilter
@@ -320,13 +321,10 @@ public final class OAuth2ClientConfigurer<B extends HttpSecurityBuilder<B>>
 		@SuppressWarnings("unchecked")
 		private <T> T getBeanOrNull(ResolvableType type) {
 			ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
-			if (context != null) {
-				String[] names = context.getBeanNamesForType(type);
-				if (names.length == 1) {
-					return (T) context.getBean(names[0]);
-				}
+			if (context == null) {
+				return null;
 			}
-			return null;
+			return (T) context.getBeanProvider(type).getIfUnique();
 		}
 
 	}

+ 9 - 12
config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java

@@ -149,6 +149,7 @@ import org.springframework.util.ReflectionUtils;
  *
  * @author Joe Grandja
  * @author Kazuki Shimizu
+ * @author Ngoc Nhan
  * @since 5.0
  * @see HttpSecurity#oauth2Login()
  * @see OAuth2AuthorizationRequestRedirectFilter
@@ -446,12 +447,10 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
 		if (names.length > 1) {
 			throw new NoUniqueBeanDefinitionException(type, names);
 		}
-		if (names.length == 1) {
-			return (JwtDecoderFactory<ClientRegistration>) this.getBuilder()
-				.getSharedObject(ApplicationContext.class)
-				.getBean(names[0]);
-		}
-		return null;
+		return (JwtDecoderFactory<ClientRegistration>) this.getBuilder()
+			.getSharedObject(ApplicationContext.class)
+			.getBeanProvider(type)
+			.getIfUnique();
 	}
 
 	private GrantedAuthoritiesMapper getGrantedAuthoritiesMapper() {
@@ -503,15 +502,13 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
 		return (bean != null) ? bean : new DefaultOAuth2UserService();
 	}
 
+	@SuppressWarnings("unchecked")
 	private <T> T getBeanOrNull(ResolvableType type) {
 		ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
-		if (context != null) {
-			String[] names = context.getBeanNamesForType(type);
-			if (names.length == 1) {
-				return (T) context.getBean(names[0]);
-			}
+		if (context == null) {
+			return null;
 		}
-		return null;
+		return (T) context.getBeanProvider(type).getIfUnique();
 	}
 
 	private void initDefaultLoginFilter(B http) {

+ 5 - 6
config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OidcLogoutConfigurer.java

@@ -65,6 +65,7 @@ import org.springframework.util.Assert;
  * </ul>
  *
  * @author Josh Cummings
+ * @author Ngoc Nhan
  * @since 6.2
  * @see HttpSecurity#oidcLogout()
  * @see OidcBackChannelLogoutFilter
@@ -283,15 +284,13 @@ public final class OidcLogoutConfigurer<B extends HttpSecurityBuilder<B>>
 			http.addFilterBefore(filter, CsrfFilter.class);
 		}
 
+		@SuppressWarnings("unchecked")
 		private <T> T getBeanOrNull(Class<?> clazz) {
 			ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
-			if (context != null) {
-				String[] names = context.getBeanNamesForType(clazz);
-				if (names.length == 1) {
-					return (T) context.getBean(names[0]);
-				}
+			if (context == null) {
+				return null;
 			}
-			return null;
+			return (T) context.getBeanProvider(clazz).getIfUnique();
 		}
 
 		private static final class EitherLogoutHandler implements LogoutHandler {

+ 2 - 7
config/src/main/java/org/springframework/security/config/annotation/web/configurers/ott/OneTimeTokenLoginConfigurer.java

@@ -21,7 +21,6 @@ import java.util.Map;
 
 import jakarta.servlet.http.HttpServletRequest;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.AuthenticationManager;
@@ -321,12 +320,8 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
 		if (context == null) {
 			return null;
 		}
-		try {
-			return context.getBean(clazz);
-		}
-		catch (NoSuchBeanDefinitionException ex) {
-			return null;
-		}
+
+		return context.getBeanProvider(clazz).getIfUnique();
 	}
 
 	private Map<String, String> hiddenInputs(HttpServletRequest request) {

+ 2 - 8
config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -24,7 +24,6 @@ import java.util.Map;
 import jakarta.servlet.http.HttpServletRequest;
 import org.opensaml.core.Version;
 
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.AuthenticationProvider;
@@ -501,12 +500,7 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
 		if (context == null) {
 			return null;
 		}
-		try {
-			return context.getBean(clazz);
-		}
-		catch (NoSuchBeanDefinitionException ex) {
-			return null;
-		}
+		return context.getBeanProvider(clazz).getIfUnique();
 	}
 
 	private <C> void setSharedObject(B http, Class<C> clazz, C object) {

+ 2 - 4
config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LogoutConfigurer.java

@@ -107,6 +107,7 @@ import org.springframework.security.web.util.matcher.RequestMatcher;
  * Uses {@link CsrfTokenRepository} to add the {@link CsrfLogoutHandler}.
  *
  * @author Josh Cummings
+ * @author Ngoc Nhan
  * @since 5.6
  * @see Saml2LogoutConfigurer
  */
@@ -336,10 +337,7 @@ public final class Saml2LogoutConfigurer<H extends HttpSecurityBuilder<H>>
 		if (this.context == null) {
 			return null;
 		}
-		if (this.context.getBeanNamesForType(clazz).length == 0) {
-			return null;
-		}
-		return this.context.getBean(clazz);
+		return this.context.getBeanProvider(clazz).getIfAvailable();
 	}
 
 	/**

+ 2 - 5
config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2MetadataConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2023 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -174,10 +174,7 @@ public class Saml2MetadataConfigurer<H extends HttpSecurityBuilder<H>>
 		if (this.context == null) {
 			return null;
 		}
-		if (this.context.getBeanNamesForType(clazz).length == 0) {
-			return null;
-		}
-		return this.context.getBean(clazz);
+		return this.context.getBeanProvider(clazz).getIfAvailable();
 	}
 
 }

+ 4 - 12
config/src/main/java/org/springframework/security/config/authentication/AuthenticationManagerFactoryBean.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -40,6 +40,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
  * has forgotten to declare the &lt;authentication-manager&gt; element.
  *
  * @author Luke Taylor
+ * @author Ngoc Nhan
  * @since 3.0
  */
 public class AuthenticationManagerFactoryBean implements FactoryBean<AuthenticationManager>, BeanFactoryAware {
@@ -61,13 +62,13 @@ public class AuthenticationManagerFactoryBean implements FactoryBean<Authenticat
 			if (!BeanIds.AUTHENTICATION_MANAGER.equals(ex.getBeanName())) {
 				throw ex;
 			}
-			UserDetailsService uds = getBeanOrNull(UserDetailsService.class);
+			UserDetailsService uds = this.bf.getBeanProvider(UserDetailsService.class).getIfUnique();
 			if (uds == null) {
 				throw new NoSuchBeanDefinitionException(BeanIds.AUTHENTICATION_MANAGER, MISSING_BEAN_ERROR_MESSAGE);
 			}
 			DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
 			provider.setUserDetailsService(uds);
-			PasswordEncoder passwordEncoder = getBeanOrNull(PasswordEncoder.class);
+			PasswordEncoder passwordEncoder = this.bf.getBeanProvider(PasswordEncoder.class).getIfUnique();
 			if (passwordEncoder != null) {
 				provider.setPasswordEncoder(passwordEncoder);
 			}
@@ -99,13 +100,4 @@ public class AuthenticationManagerFactoryBean implements FactoryBean<Authenticat
 		this.observationRegistry = observationRegistry;
 	}
 
-	private <T> T getBeanOrNull(Class<T> type) {
-		try {
-			return this.bf.getBean(type);
-		}
-		catch (NoSuchBeanDefinitionException noUds) {
-			return null;
-		}
-	}
-
 }

+ 4 - 8
config/src/main/java/org/springframework/security/config/http/GrantedAuthorityDefaultsParserUtils.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2012-2018 the original author or authors.
+ * Copyright 2012-2024 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.
@@ -25,6 +25,7 @@ import org.springframework.security.config.core.GrantedAuthorityDefaults;
 
 /**
  * @author Rob Winch
+ * @author Ngoc Nhan
  * @since 4.2
  */
 final class GrantedAuthorityDefaultsParserUtils {
@@ -49,13 +50,8 @@ final class GrantedAuthorityDefaultsParserUtils {
 
 		@Override
 		public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-			String[] grantedAuthorityDefaultsBeanNames = applicationContext
-				.getBeanNamesForType(GrantedAuthorityDefaults.class);
-			if (grantedAuthorityDefaultsBeanNames.length == 1) {
-				GrantedAuthorityDefaults grantedAuthorityDefaults = applicationContext
-					.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
-				this.rolePrefix = grantedAuthorityDefaults.getRolePrefix();
-			}
+			applicationContext.getBeanProvider(GrantedAuthorityDefaults.class)
+				.ifUnique((grantedAuthorityDefaults) -> this.rolePrefix = grantedAuthorityDefaults.getRolePrefix());
 		}
 
 		abstract Object getBean();

+ 4 - 8
config/src/main/java/org/springframework/security/config/method/GlobalMethodSecurityBeanDefinitionParser.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -88,6 +88,7 @@ import org.springframework.util.xml.DomUtils;
  * @author Ben Alex
  * @author Luke Taylor
  * @author Rob Winch
+ * @author Ngoc Nhan
  * @since 2.0
  * @deprecated Use {@link MethodSecurityBeanDefinitionParser} instead
  */
@@ -483,13 +484,8 @@ public class GlobalMethodSecurityBeanDefinitionParser implements BeanDefinitionP
 
 		@Override
 		public final void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-			String[] grantedAuthorityDefaultsBeanNames = applicationContext
-				.getBeanNamesForType(GrantedAuthorityDefaults.class);
-			if (grantedAuthorityDefaultsBeanNames.length == 1) {
-				GrantedAuthorityDefaults grantedAuthorityDefaults = applicationContext
-					.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
-				this.rolePrefix = grantedAuthorityDefaults.getRolePrefix();
-			}
+			applicationContext.getBeanProvider(GrantedAuthorityDefaults.class)
+				.ifUnique((grantedAuthorityDefaults) -> this.rolePrefix = grantedAuthorityDefaults.getRolePrefix());
 		}
 
 	}

+ 8 - 15
config/src/main/java/org/springframework/security/config/method/MethodSecurityBeanDefinitionParser.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -67,6 +67,7 @@ import org.springframework.util.xml.DomUtils;
  * Processes the top-level "method-security" element.
  *
  * @author Josh Cummings
+ * @author Ngoc Nhan
  * @since 5.6
  */
 public class MethodSecurityBeanDefinitionParser implements BeanDefinitionParser {
@@ -307,13 +308,9 @@ public class MethodSecurityBeanDefinitionParser implements BeanDefinitionParser
 
 		@Override
 		public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-			String[] grantedAuthorityDefaultsBeanNames = applicationContext
-				.getBeanNamesForType(GrantedAuthorityDefaults.class);
-			if (grantedAuthorityDefaultsBeanNames.length == 1) {
-				GrantedAuthorityDefaults grantedAuthorityDefaults = applicationContext
-					.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
-				this.expressionHandler.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix());
-			}
+			applicationContext.getBeanProvider(GrantedAuthorityDefaults.class)
+				.ifUnique((grantedAuthorityDefaults) -> this.expressionHandler
+					.setDefaultRolePrefix(grantedAuthorityDefaults.getRolePrefix()));
 		}
 
 	}
@@ -347,13 +344,9 @@ public class MethodSecurityBeanDefinitionParser implements BeanDefinitionParser
 
 		@Override
 		public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
-			String[] grantedAuthorityDefaultsBeanNames = applicationContext
-				.getBeanNamesForType(GrantedAuthorityDefaults.class);
-			if (grantedAuthorityDefaultsBeanNames.length == 1) {
-				GrantedAuthorityDefaults grantedAuthorityDefaults = applicationContext
-					.getBean(grantedAuthorityDefaultsBeanNames[0], GrantedAuthorityDefaults.class);
-				this.manager.setRolePrefix(grantedAuthorityDefaults.getRolePrefix());
-			}
+			applicationContext.getBeanProvider(GrantedAuthorityDefaults.class)
+				.ifUnique((grantedAuthorityDefaults) -> this.manager
+					.setRolePrefix(grantedAuthorityDefaults.getRolePrefix()));
 		}
 
 		public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy securityContextHolderStrategy) {

+ 4 - 8
config/src/main/java/org/springframework/security/config/web/server/ServerHttpSecurity.java

@@ -1734,26 +1734,22 @@ public class ServerHttpSecurity {
 	}
 
 	private <T> T getBeanOrDefault(Class<T> beanClass, T defaultInstance) {
-		T bean = getBeanOrNull(beanClass);
-		if (bean == null) {
+		if (this.context == null) {
 			return defaultInstance;
 		}
-		return bean;
+		return this.context.getBeanProvider(beanClass).getIfUnique(() -> defaultInstance);
 	}
 
 	private <T> T getBeanOrNull(Class<T> beanClass) {
 		return getBeanOrNull(ResolvableType.forClass(beanClass));
 	}
 
+	@SuppressWarnings("unchecked")
 	private <T> T getBeanOrNull(ResolvableType type) {
 		if (this.context == null) {
 			return null;
 		}
-		String[] names = this.context.getBeanNamesForType(type);
-		if (names.length == 1) {
-			return (T) this.context.getBean(names[0]);
-		}
-		return null;
+		return (T) this.context.getBeanProvider(type).getIfUnique();
 	}
 
 	private <T> T getBeanOrNull(String beanName, Class<T> requiredClass) {