Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot Filter error, Failed to register after unregistered Filter

Im both new to Spring Boot and Kotlin.

I'm having an error saying that

Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: 
Cannot register after unregistered Filter class com.jxinternet.platform.ms.merchant.config.security.ReplaceResponseFilter


2018-10-03 15:50:21.601 ERROR 63436 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Cannot register after unregistered Filter class com.jxinternet.platform.ms.merchant.config.security.ReplaceResponseFilter
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:587)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1250)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:541)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:501)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:760)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
    at com.jxinternet.platform.ms.merchant.MerchantApplicationKt.main(MerchantApplication.kt:28)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Cannot register after unregistered Filter class com.jxinternet.platform.ms.merchant.config.security.ReplaceResponseFilter
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:579)
    ... 20 common frames omitted
Caused by: java.lang.IllegalArgumentException: Cannot register after unregistered Filter class com.jxinternet.platform.ms.merchant.config.security.ReplaceResponseFilter
    at org.springframework.security.config.annotation.web.builders.FilterComparator.registerAfter(FilterComparator.java:156)
    at org.springframework.security.config.annotation.web.builders.HttpSecurity.addFilterAfter(HttpSecurity.java:1121)
    at com.jxinternet.platform.ms.merchant.config.security.WebSecurityConfig.configure(WebSecurityConfig.kt:64)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:230)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:321)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:92)
    at com.jxinternet.platform.ms.merchant.config.security.WebSecurityConfig$$EnhancerBySpringCGLIB$$7e2d609b.init(<generated>)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:371)
    at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:325)
    at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:104)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$f5effa1c.CGLIB$springSecurityFilterChain$3(<generated>)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$f5effa1c$$FastClassBySpringCGLIB$$d83091e8.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361)
    at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$f5effa1c.springSecurityFilterChain(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 21 common frames omitted

Disconnected from the target VM, address: '127.0.0.1:51914', transport: 'socket'

Process finished with exit code 1

my ReplaceResponseFilter.kt

package com.jxinternet.platform.ms.merchant.config.security

import org.slf4j.LoggerFactory
import org.springframework.context.annotation.Configuration
import org.springframework.core.annotation.Order
import org.springframework.hateoas.VndErrors
import org.springframework.http.HttpStatus
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.web.filter.GenericFilterBean
import javax.servlet.*
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpServletResponseWrapper


open class ReplaceResponseFilter : Filter {

    companion object {
        private val log = LoggerFactory.getLogger(ReplaceResponseFilter::class.java)
    }

    override fun doFilter(request: ServletRequest, response: ServletResponse, filterChain: FilterChain) {

        val t = response as HttpServletResponseWrapper


    }

    override fun init(p0: FilterConfig?) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun destroy(){

    }


}

my WebSecurityConfig.kt

package com.jxinternet.platform.ms.merchant.config.security

import com.fasterxml.jackson.databind.ObjectMapper
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.builders.WebSecurity
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
import org.springframework.security.config.http.SessionCreationPolicy
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.security.web.firewall.HttpFirewall
import org.springframework.security.web.firewall.StrictHttpFirewall



@Configuration
@EnableWebSecurity
class WebSecurityConfig(
        private val tokenAuthenticationService: TokenAuthenticationService,
        private val objectMapper: ObjectMapper
) : WebSecurityConfigurerAdapter() {

    // 防止防止url带两个// spring security 5会有问题 所以必须放开这个配置
    @Bean
    fun allowUrlEncodedSlashHttpFirewall(): HttpFirewall {
        val firewall = StrictHttpFirewall()
        firewall.setAllowUrlEncodedSlash(true)
        return firewall
    }

    override fun configure(web: WebSecurity) {
        super.configure(web)
        web.httpFirewall(allowUrlEncodedSlashHttpFirewall())
    }

    // 设置 HTTP 验证规则
    override fun configure(http: HttpSecurity) {
        // 关闭csrf验证
        http.csrf().disable()
                // 对请求进行认证
                .authorizeRequests()
                // 所有 / 的所有请求 都放行
                .antMatchers(
                        "/",
                        "/pay/**",
                        "/scan/**",
                        "/login",
                        "/actuator/health",
                        "/webjars/springfox-swagger-ui/**",
                        "/swagger-ui.html",
                        "/configuration/ui",
                        "/swagger-resources",
                        "/v2/api-docs",
                        "/swagger-resources/**").permitAll()
                // 所有 /login 的POST请求 都放行
                // 所有请求需要身份认证
                .anyRequest().authenticated()
                .and()
                // 添加一个过滤器 所有访问 /login 的请求交给 JWTLoginFilter 来处理 这个类处理所有的JWT相关内容
                //.addFilterBefore(loginFilter(objectMapper, tokenAuthenticationService), UsernamePasswordAuthenticationFilter::class.java)
                // 添加一个过滤器验证其他请求的Token是否合法
                .addFilterBefore(JWTAuthenticationFilter(tokenAuthenticationService, objectMapper), UsernamePasswordAuthenticationFilter::class.java)
                .addFilterAfter(ReplaceResponseFilter(), ReplaceResponseFilter::class.java)
                // 设置session无状态!!
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)

    }

}
like image 525
SicaYoumi Avatar asked Mar 06 '23 07:03

SicaYoumi


1 Answers

In ReplaceResponseFilter, you're missing:

filterChain.doFilter(request, response)

Otherwise, your filter chain cannot continue. I also believe that this is incorrect:

.addFilterAfter(ReplaceResponseFilter(), ReplaceResponseFilter::class.java)

As far as I understand your code, that filter should come after JWTAuthenticationFilter. Therefore:

.addFilterAfter(ReplaceResponseFilter(), JWTAuthenticationFilter::class.java)
like image 173
Branislav Lazic Avatar answered Apr 26 '23 01:04

Branislav Lazic