Skip to content

SpringBootWebSecurityConfiguration missing @EnableWebSecurity #10236

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

Closed
jgrandja opened this issue Sep 9, 2017 · 3 comments
Closed

SpringBootWebSecurityConfiguration missing @EnableWebSecurity #10236

jgrandja opened this issue Sep 9, 2017 · 3 comments
Labels
status: invalid An issue that we don't feel is valid

Comments

@jgrandja
Copy link

jgrandja commented Sep 9, 2017

When I run the tests in OAuth2ClientAutoConfigurationTests, I get the following exception:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.security.SpringBootWebSecurityConfiguration$DefaultConfigurerAdapter': Unsatisfied dependency expressed through method 'setObjectPostProcessor' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.config.annotation.ObjectPostProcessor<java.lang.Object>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

This exception is caused because SpringBootWebSecurityConfiguration.DefaultConfigurerAdapter is not annotated with @EnableWebSecurity.

SpringBootWebSecurityConfiguration.DefaultConfigurerAdapter is annotated with @Configuration and extends WebSecurityConfigurerAdapter. So the expectation would be that WebSecurityEnablerConfiguration will automatically import the required @Configuration's because it's annotated with @EnableWebSecurity for these specific cases.

However, WebSecurityEnablerConfiguration does not kick in at all because when the context creates and then tries to auto-wire SpringBootWebSecurityConfiguration.DefaultConfigurerAdapter.setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) it can't find the required dependency in the context and so the exception is triggered.

If you replace the @Configuration with @EnableWebSecurity then the tests will pass. For example:

	@EnableWebSecurity
	@Order(SecurityProperties.BASIC_AUTH_ORDER)
	static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {

When a class extends WebSecurityConfigurerAdapter, it should also be annotated with @EnableWebSecurity to ensure the required @Configuration's are imported.

@wilkinsona
Copy link
Member

@EnableWebSecurity is applied, if necessary, by WebSecurityEnablerConfiguration. I suspect you need to import it in your test. I don't think we want to add @EnableWebSecurity to SpringBootWebSecurityConfiguration as is proposed here.

@wilkinsona wilkinsona added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 9, 2017
@jgrandja
Copy link
Author

jgrandja commented Sep 9, 2017

I already tried importing WebSecurityEnablerConfiguration in my tests and that did not resolve it.

I'm actually suggesting to add @EnableWebSecurity to the inner class DefaultConfigurerAdapter of SpringBootWebSecurityConfiguration as suggested in my previous comment:

@ConditionalOnProperty(prefix = "security.basic", name = "enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnClass(EnableWebSecurity.class)
@ConditionalOnMissingBean(WebSecurityConfigurerAdapter.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
public class SpringBootWebSecurityConfiguration {

	@EnableWebSecurity
	@Order(SecurityProperties.BASIC_AUTH_ORDER)
	static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {

This is the designed approach when enabling security - when extending WebSecurityConfigurerAdapter you also annotate the class with @EnableWebSecurity which indirectly imports ObjectPostProcessorConfiguration which creates the ObjectPostProcessor that is needed for auto-wiring into WebSecurityConfigurerAdapter.

Although WebSecurityEnablerConfiguration is annotated with @ConditionalOnBean(WebSecurityConfigurerAdapter.class) which looks like it satisfies the condition of:

	@Configuration
	@Order(SecurityProperties.BASIC_AUTH_ORDER)
	static class DefaultConfigurerAdapter extends WebSecurityConfigurerAdapter {

it does not kick in before the auto-wiring of SpringBootWebSecurityConfiguration.DefaultConfigurerAdapter.setObjectPostProcessor(ObjectPostProcessor<Object> objectPostProcessor) happens and therefore resulting in the unsatisfied deps.

My suspicion is that it's because DefaultConfigurerAdapter is annotated with @Configuration and not @Bean. Even though they are both @Component it seems the bootstrap process is not cycling in the expected order so WebSecurityEnablerConfiguration condition is not satisfied.

Does ConditionalOnBean work the same for @Configuration as it does for @Bean?

@jgrandja
Copy link
Author

@wilkinsona So I figured out that this is actually an ordering issue. Thanks to your comment that gave me this clue.

this.context.register(SecurityAutoConfiguration.class, OAuth2ClientAutoConfiguration.class) triggers the issue.

whereas

this.context.register(OAuth2ClientAutoConfiguration.class, SecurityAutoConfiguration.class) works just fine

So there is an ordering issue going on here with the auto-config classes. I'm going to re-work things based on some of your comments in the PR.
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

3 participants