Auto config AuthenticationPrincipalArgumentResolver When AnnotationTemplateExpressionDefaults bean is Present

This commit is contained in:
DingHao 2024-07-30 11:07:59 +08:00 committed by Josh Cummings
parent f4d9d0d54f
commit 895978c818
4 changed files with 29 additions and 2 deletions

View File

@ -40,6 +40,7 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.BeanResolver; import org.springframework.expression.BeanResolver;
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy; import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.FilterChainProxy;
@ -82,12 +83,15 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder private SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder
.getContextHolderStrategy(); .getContextHolderStrategy();
private AnnotationTemplateExpressionDefaults templateDefaults;
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
AuthenticationPrincipalArgumentResolver authenticationPrincipalResolver = new AuthenticationPrincipalArgumentResolver(); AuthenticationPrincipalArgumentResolver authenticationPrincipalResolver = new AuthenticationPrincipalArgumentResolver();
authenticationPrincipalResolver.setBeanResolver(this.beanResolver); authenticationPrincipalResolver.setBeanResolver(this.beanResolver);
authenticationPrincipalResolver.setSecurityContextHolderStrategy(this.securityContextHolderStrategy); authenticationPrincipalResolver.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
authenticationPrincipalResolver.setTemplateDefaults(this.templateDefaults);
argumentResolvers.add(authenticationPrincipalResolver); argumentResolvers.add(authenticationPrincipalResolver);
argumentResolvers argumentResolvers
.add(new org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver()); .add(new org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver());
@ -109,6 +113,9 @@ class WebMvcSecurityConfiguration implements WebMvcConfigurer, ApplicationContex
if (applicationContext.getBeanNamesForType(SecurityContextHolderStrategy.class).length == 1) { if (applicationContext.getBeanNamesForType(SecurityContextHolderStrategy.class).length == 1) {
this.securityContextHolderStrategy = applicationContext.getBean(SecurityContextHolderStrategy.class); this.securityContextHolderStrategy = applicationContext.getBean(SecurityContextHolderStrategy.class);
} }
if (applicationContext.getBeanNamesForType(AnnotationTemplateExpressionDefaults.class).length == 1) {
this.templateDefaults = applicationContext.getBean(AnnotationTemplateExpressionDefaults.class);
}
} }
/** /**

View File

@ -34,6 +34,7 @@ import org.springframework.security.authentication.ReactiveAuthenticationManager
import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager; import org.springframework.security.authentication.UserDetailsRepositoryReactiveAuthenticationManager;
import org.springframework.security.authentication.password.ReactiveCompromisedPasswordChecker; import org.springframework.security.authentication.password.ReactiveCompromisedPasswordChecker;
import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
import org.springframework.security.core.userdetails.ReactiveUserDetailsPasswordService; import org.springframework.security.core.userdetails.ReactiveUserDetailsPasswordService;
import org.springframework.security.core.userdetails.ReactiveUserDetailsService; import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
@ -120,12 +121,14 @@ class ServerHttpSecurityConfiguration {
} }
@Bean @Bean
AuthenticationPrincipalArgumentResolver authenticationPrincipalArgumentResolver() { AuthenticationPrincipalArgumentResolver authenticationPrincipalArgumentResolver(
ObjectProvider<AnnotationTemplateExpressionDefaults> templateDefaults) {
AuthenticationPrincipalArgumentResolver resolver = new AuthenticationPrincipalArgumentResolver( AuthenticationPrincipalArgumentResolver resolver = new AuthenticationPrincipalArgumentResolver(
this.adapterRegistry); this.adapterRegistry);
if (this.beanFactory != null) { if (this.beanFactory != null) {
resolver.setBeanResolver(new BeanFactoryResolver(this.beanFactory)); resolver.setBeanResolver(new BeanFactoryResolver(this.beanFactory));
} }
templateDefaults.ifAvailable(resolver::setTemplateDefaults);
return resolver; return resolver;
} }

View File

@ -35,6 +35,7 @@ import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.security.authorization.AuthorizationManager; import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.authorization.ObservationAuthorizationManager; import org.springframework.security.authorization.ObservationAuthorizationManager;
import org.springframework.security.authorization.SpringAuthorizationEventPublisher; import org.springframework.security.authorization.SpringAuthorizationEventPublisher;
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy; import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor; import org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor;
@ -82,6 +83,8 @@ final class WebSocketMessageBrokerSecurityConfiguration
private ApplicationContext context; private ApplicationContext context;
private AnnotationTemplateExpressionDefaults templateDefaults;
WebSocketMessageBrokerSecurityConfiguration(ApplicationContext context) { WebSocketMessageBrokerSecurityConfiguration(ApplicationContext context) {
this.context = context; this.context = context;
} }
@ -90,6 +93,7 @@ final class WebSocketMessageBrokerSecurityConfiguration
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
AuthenticationPrincipalArgumentResolver resolver = new AuthenticationPrincipalArgumentResolver(); AuthenticationPrincipalArgumentResolver resolver = new AuthenticationPrincipalArgumentResolver();
resolver.setSecurityContextHolderStrategy(this.securityContextHolderStrategy); resolver.setSecurityContextHolderStrategy(this.securityContextHolderStrategy);
resolver.setTemplateDefaults(this.templateDefaults);
argumentResolvers.add(resolver); argumentResolvers.add(resolver);
} }
@ -128,6 +132,11 @@ final class WebSocketMessageBrokerSecurityConfiguration
this.observationRegistry = observationRegistry; this.observationRegistry = observationRegistry;
} }
@Autowired(required = false)
void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) {
this.templateDefaults = templateDefaults;
}
@Override @Override
public void afterSingletonsInstantiated() { public void afterSingletonsInstantiated() {
SimpleUrlHandlerMapping mapping = getBeanOrNull(SIMPLE_URL_HANDLER_MAPPING_BEAN_NAME, SimpleUrlHandlerMapping mapping = getBeanOrNull(SIMPLE_URL_HANDLER_MAPPING_BEAN_NAME,

View File

@ -305,6 +305,8 @@ public final class WebSocketMessageBrokerSecurityBeanDefinitionParser implements
private static final String CUSTOM_ARG_RESOLVERS_PROP = "customArgumentResolvers"; private static final String CUSTOM_ARG_RESOLVERS_PROP = "customArgumentResolvers";
private static final String TEMPLATE_EXPRESSION_BEAN_ID = "templateDefaults";
private final String inboundSecurityInterceptorId; private final String inboundSecurityInterceptorId;
private final boolean sameOriginDisabled; private final boolean sameOriginDisabled;
@ -327,7 +329,13 @@ public final class WebSocketMessageBrokerSecurityBeanDefinitionParser implements
if (current != null) { if (current != null) {
argResolvers.addAll((ManagedList<?>) current.getValue()); argResolvers.addAll((ManagedList<?>) current.getValue());
} }
argResolvers.add(new RootBeanDefinition(AuthenticationPrincipalArgumentResolver.class)); RootBeanDefinition beanDefinition = new RootBeanDefinition(
AuthenticationPrincipalArgumentResolver.class);
if (registry.containsBeanDefinition(TEMPLATE_EXPRESSION_BEAN_ID)) {
beanDefinition.getPropertyValues()
.add(TEMPLATE_EXPRESSION_BEAN_ID, new RuntimeBeanReference(TEMPLATE_EXPRESSION_BEAN_ID));
}
argResolvers.add(beanDefinition);
bd.getPropertyValues().add(CUSTOM_ARG_RESOLVERS_PROP, argResolvers); bd.getPropertyValues().add(CUSTOM_ARG_RESOLVERS_PROP, argResolvers);
if (!registry.containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) { if (!registry.containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) {
PropertyValue pathMatcherProp = bd.getPropertyValues().getPropertyValue("pathMatcher"); PropertyValue pathMatcherProp = bd.getPropertyValues().getPropertyValue("pathMatcher");