Vlad  Yurevich
Vlad Yurevich

Reputation: 305

Can't use WebSecurityConfigurerAdapter in a custom spring boot starter

I'm trying to create my own spring boot starter for my custom security configuration (LDAP + JWT) via defining configuration class which extends from WebSecurityConfigurerAdapter. However, when I launch my application with this starter I get:

IllegalStateException: Found WebSecurityConfigurerAdapter as well as SecurityFilterChain.
Please select just one.

I found out that it's not possible any longer to do that due to this issue of the spring security. There is an assertion in WebSecurityConfiguration of the spring:

Snapshot from WebSecurityConfiguration.java

I solved this adding to the starter the following (according to the issue):

@Bean
@Order(1) //Explanation for this below
open fun filterChain(http: HttpSecurity, jwtHelper: JwtHelper): SecurityFilterChain {
    return http.authorizeRequests()
           ...
               .addFilterBefore(JwtAuthenticationFilter(jwtHelper), UsernamePasswordAuthenticationFilter::class.java)
               .and().build()
}

@Bean
open fun authenticationProvider(ldapConfig: LdapConfig): ActiveDirectoryLdapAuthenticationProvider {
    return ActiveDirectoryLdapAuthenticationProvider(...)
}

I added @Order(1) because there are two securityFilterChains: mine (defined in the configurartion above) and another one from an unknown source. I suppose, the latter is the reason of impossibility of using WebSecurityConfigurerAdapter.

The main problem is that I can't find where that comes from.


Breakpoint from WebSecurityConfiguration... just in case: Break point from WebSecurityConfiguration

I assume, because of that I can't use @EnableGlobalMethodSecurity(prePostEnabled = true) as well. It says:

Cannot apply org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration$EnableGlobalAuthenticationAutowiredConfigurer
to already built object

Here is list of my dependencies:

  1. Module with models which is used by the starter (name: my-ldap-security-model):
dependencies {
    compileOnly 'org.springframework.security:spring-security-core'
    compileOnly 'org.springframework:spring-web'
    compileOnly 'javax.servlet:javax.servlet-api'
    api 'jakarta.xml.bind:jakarta.xml.bind-api'
    api 'org.glassfish.jaxb:jaxb-runtime'
    api 'io.jsonwebtoken:jjwt'
}
  1. Module with models which is used by the starter (name: my-ldap-security-spring-boot-starter):
dependencies {
    compile project(':my-ldap-security-model')
    compileOnly 'javax.servlet:javax.servlet-api'
    api 'org.springframework.security:spring-security-core'
    api 'org.springframework.security:spring-security-config'
    api 'org.springframework.security:spring-security-web'
    api 'org.springframework:spring-web'
    api 'org.springframework.security:spring-security-ldap'
}
  1. App project:
dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    implementation('com.demo.boot:my-ldap-security-spring-boot-starter:0.0.1')
}

Please, help me find out the root of that filter.

Upvotes: 6

Views: 12383

Answers (4)

marichibo
marichibo

Reputation: 1

I resolved same error by changing order of servlets in web.xml. ↓ no problem order xxx -> yyy 〇  yyy -> xxx ×

<servlet>
   <servlet-name>xxxServlet</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   … ommit
</servlet>
<servlet-mapping>
   <servlet-name>xxxServlet</servlet-name>
   <url-pattern>/</url-pattern>
</servlet-mapping>
<servlet> 
    <servlet-name>yyyServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   … ommit
</servlet>
<servlet-mapping>
     <servlet-name>yyyServlet</servlet-name>
     <url-pattern>/yyy/*</url-pattern>
</servlet-mapping>

Upvotes: 0

Shree Krishna
Shree Krishna

Reputation: 8562

For googlers

You can't use

@Bean
public SecurityFilterChain filterChain(HttpSecurity http)...

while extending WebSecurityConfigurerAdapter.

Either choose above one or only override

@Override
protected void configure(HttpSecurity http)

Upvotes: 3

mabreu0
mabreu0

Reputation: 90

Take a look at project structure, there might be a securityFilterChain coming from xml configuration rather than class extension. XML with http tag.

Upvotes: 0

Vlad  Yurevich
Vlad Yurevich

Reputation: 305

Initially, the default SecurityFilterChain are disabled if there is any WebSecurityConfigurerAdapter. However, it doesn't work if the priority of the spring security auto-configuration is higher than auto-configuration with your WebSecurityConfigurerAdapter.

Solution: I added @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) above the auto-configuration class. There is no default security filter chain any longer :)

About @EnableGlobalMethodSecurity... It was about caches. Suddenly, it got fixed.

Upvotes: 4

Related Questions