Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve ObjectPostProcessor collisions between RSocket and WebFlux security configuration #16161

Closed
joaodias14 opened this issue Nov 25, 2024 · 4 comments
Assignees
Labels
in: config An issue in spring-security-config type: bug A general bug
Milestone

Comments

@joaodias14
Copy link

While migrating to the new Spring Boot 3.4 version I am facing the following error in a project with RSocket, Spring Security and Spring Webflux:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method setAuthenticationManagerPostProcessor in org.springframework.security.config.annotation.web.reactive.ServerHttpSecurityConfiguration required a single bean, but 2 were found:
	- authenticationManagerPostProcessor: defined by method 'authenticationManagerPostProcessor' in class path resource [org/springframework/security/config/annotation/web/reactive/ReactiveObservationConfiguration.class]
	- rSocketAuthenticationManagerPostProcessor: defined by method 'rSocketAuthenticationManagerPostProcessor' in class path resource [org/springframework/security/config/annotation/rsocket/ReactiveObservationConfiguration.class]

This may be due to missing parameter name information

Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

I was able to reproduce this in a simple project which you can find at https://github.com/joaodias14/Spring-Boot-RSocket. I simply used https://start.spring.io/ with Spring Boot 3.4.0 and RSocket, Spring Reactive Web and Spring Security as dependencies. If I run it with ./mvnw -o spring-boot:run I get the error above.

@jzheaux
Copy link
Contributor

jzheaux commented Nov 25, 2024

Thanks for the report, @joaodias14. I'm able to reproduce this issue; we'll get a fix out in the next maintenance release.

In the meantime, if you are not using Security's Observability integration, then you can do:

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Primary
static ObjectPostProcessor<ReactiveAuthorizationManager<ServerWebExchange>> primaryAuthorizationManagerPostProcessor() {
	return ObjectPostProcessor.identity();
}

@Bean
@Role(2)
@Primary
static ObjectPostProcessor<ReactiveAuthenticationManager> primaryAuthenticationManagerPostProcessor() {
	return ObjectPostProcessor.identity();
}

@Bean
@Role(2)
@Primary
static ObjectPostProcessor<WebFilterChainProxy.WebFilterChainDecorator> primaryFilterChainDecoratorPostProcessor() {
	return ObjectPostProcessor.identity();
}

Or, if you are, then you can instead do:

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Primary
static ObjectPostProcessor<ReactiveAuthorizationManager<ServerWebExchange>> primaryAuthorizationManagerPostProcessor(
	ObjectProvider<ObservationRegistry> registry) {
	return new ObjectPostProcessor<>() {
		@Override
		public ReactiveAuthorizationManager postProcess(ReactiveAuthorizationManager object) {
			ObservationRegistry r = registry.getIfUnique(() -> ObservationRegistry.NOOP);
			return new ObservationReactiveAuthorizationManager<>(r, object);
		}
	};
}

@Bean
@Role(2)
@Primary
static ObjectPostProcessor<ReactiveAuthenticationManager> primaryAuthenticationManagerPostProcessor(ObjectProvider<ObservationRegistry> registry) {
	return new ObjectPostProcessor<>() {
		public ReactiveAuthenticationManager postProcess(ReactiveAuthenticationManager object) {
			ObservationRegistry r = registry.getIfUnique(() -> ObservationRegistry.NOOP);
			return new ObservationReactiveAuthenticationManager(r, object);
		}
	};
}

@Bean
@Role(2)
@Primary
static ObjectPostProcessor<WebFilterChainProxy.WebFilterChainDecorator> primaryFilterChainDecoratorPostProcessor(ObjectProvider<ObservationRegistry> registry) {
	return new ObjectPostProcessor<>() {
		public WebFilterChainProxy.WebFilterChainDecorator postProcess(WebFilterChainProxy.WebFilterChainDecorator object) {
			ObservationRegistry r = registry.getIfUnique(() -> ObservationRegistry.NOOP);
			return new ObservationWebFilterChainDecorator(r);
		}
	};
}

@jzheaux jzheaux added this to the 6.4.2 milestone Nov 25, 2024
@ngocnhan-tran1996
Copy link
Contributor

@jzheaux

We will add @Primary or have another handle way when both RSocket and Webflux are on classpath?

@jzheaux jzheaux changed the title Spring Boot 3.4.0 / Spring Security 6.4.1 - Multiple ObjectPostProcessor<ReactiveAuthenticationManager> when a single one is expected Resolve ObjectPostProcessor collisions between RSocket and WebFlux security configuration Nov 25, 2024
@joaodias14
Copy link
Author

Many thanks for the quick workaround @jzheaux !

@jzheaux
Copy link
Contributor

jzheaux commented Nov 25, 2024

Good question, @ngocnhan-tran1996, please see the commit for details; it disambiguates in the setter to preserve Spring Security's getIfUnique semantics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: config An issue in spring-security-config type: bug A general bug
Projects
Status: No status
Development

No branches or pull requests

3 participants