복붙노트

[SPRING] Spring 부트에서 구성된 @Autowired 필터 사용

SPRING

Spring 부트에서 구성된 @Autowired 필터 사용

필터에 autowired를 사용해야합니다. 따라서 @Component를 사용하여 필자의 필터 클래스에 주석을 달았습니다.

import org.springframework.web.filter.GenericFilterBean;
@Component
public class TokenAuthorizationFilter extends GenericFilterBean {
    @Autowired
    public EnrollCashRepository enrollCashRepository;
}

그런 다음 SecurityConfig에 아래와 같이 필터를 추가합니다.

   @Configuration
    @EnableWebMvcSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
        public void configure(WebSecurity webSecurity) throws Exception
        {
            webSecurity.ignoring().antMatchers(HttpMethod.GET, "/health");
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.addFilterBefore(new TokenAuthorizationFilter(), BasicAuthenticationFilter.class);  
            http.authorizeRequests().antMatchers("/api/**").authenticated();    
    }

내 문제는 내 필터가 @Component 주석으로 두 번 호출된다는 것입니다. @Component 주석을 제거하면 한 번만 호출됩니다.

그럼 내 봄 부팅 메인 클래스에서 수정 프로그램으로 아래에 추가하십시오. 그런 다음 SecurityConfig에서 addFilterBefore 라인을 주석 처리합니다.

 @Bean
    public FilterRegistrationBean tokenAuthFilterRegistration() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new PITokenAuthorizationFilter());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.setEnabled(false);
        return filterRegistrationBean;
    }

하지만 내 필터가 한 번 호출됩니다. 하지만 setEnabled를 true 또는 false로 설정하더라도 나머지 api (http : // localhost : 8080 / api / myservice)를 호출하면 403 Forbiddon 오류가 발생합니다.

스프링 필터에서 @Autowired를 사용할 수있는 상황을 어떻게 수정합니까?

편집 : 컨트롤러 및 필터 클래스 추가,

@RestController
@RequestMapping(value = "/api")
public class SpringToolController { 
    @RequestMapping(value = "/myservice", method = RequestMethod.GET)
    public HttpEntity<String> myService() {
        System.out.println("-----------myService invoke-----------");
        return new ResponseEntity<String>(HttpStatus.OK);
    }
}



public class TokenAuthorizationFilter extends GenericFilterBean {
    public TokenAuthorizationFilter(EnrollCashRepository enrollCashRepository) {
        this.enrollCashRepository = enrollCashRepository;
    }

    public EnrollCashRepository enrollCashRepository;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {
        System.out.println("before PITokenAuthorizationFilter");
        chain.doFilter(servletRequest, servletResponse);
        System.out.println("after PITokenAuthorizationFilter");
    }

    public EnrollCashRepository getEnrollCashRepository() {
        return enrollCashRepository;
    }

    public void setEnrollCashRepository(EnrollCashRepository enrollCashRepository) {
        this.enrollCashRepository = enrollCashRepository;
    }

}

해결법

  1. ==============================

    1.FilterRegistrationBean을 제거하고 다음과 같이 SecurityConfig 내부의 TokenAuthorizationFilter를 초기화하십시오.

    FilterRegistrationBean을 제거하고 다음과 같이 SecurityConfig 내부의 TokenAuthorizationFilter를 초기화하십시오.

    @Configuration
    @EnableWebMvcSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        public EnrollCashRepository enrollCashRepository;
    
        @Override
        public void configure(WebSecurity webSecurity) throws Exception
        {
            webSecurity.ignoring().antMatchers(HttpMethod.GET, "/health");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception 
        {
            http.addFilterBefore(tokenAuthorizationFilter(), BasicAuthenticationFilter.class);  
            http.authorizeRequests().antMatchers("/api/**").authenticated();    
        }
    
        private TokenAuthorizationFilter tokenAuthorizationFilter() 
        {
            return new TokenAuthorizationFilter(enrollCashRepository);
        }
    }
    

    @Autowired 및 @Component 주석을 제거하고 EnrollCashRepository를 생성자 삽입으로 설정하십시오.

    import org.springframework.web.filter.GenericFilterBean;
    
    public class TokenAuthorizationFilter extends GenericFilterBean {
    
        private final EnrollCashRepository enrollCashRepository;
    
        public TokenAuthorizationFilter(EnrollCashRepository enrollCashRepository) 
        {
            this.enrollCashRepository = enrollCashRepository
        }
    }
    
  2. ==============================

    2.이제 작업 클래스에 테스트 필터를 추가했는데 제대로 작동했습니다. 여기에 관련된 코드가 있습니다.

    이제 작업 클래스에 테스트 필터를 추가했는데 제대로 작동했습니다. 여기에 관련된 코드가 있습니다.

    @Component
    public class TestFilter extends GenericFilterBean {
    
    private static final Logger logger = LoggerFactory.getLogger(TestFilter.class);
    
    @Autowired
    UserService userService;
    
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
         logger.error("=====================AWESOME=======================");
         chain.doFilter(request, response);
         userService.activate("123"); //this works
     }
    
    }
    
    @Configuration
    @EnableWebSecurity
    public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Autowired
    private TestFilter testFilter;
    
         @Override
         protected void configure(HttpSecurity http) throws Exception {
         //loginFailureHandler.setDefaultFailureUrl("/login?error=true");
         http.addFilterBefore(testFilter, BasicAuthenticationFilter.class);
         //Http other config here.
     }
    }
    
    @Configuration
    @ImportResource({
        "classpath*:/context.xml"
    })
    @PropertySources(
        @PropertySource({
                "classpath:/application.yml"
        })
    )
    @Import({AppSecurityConfig.class, WebConfig.class,TestFilter.class})
    public class AppConfig {
    }
    
  3. from https://stackoverflow.com/questions/33537388/use-autowired-with-a-filter-configured-in-springboot by cc-by-sa and MIT license