我需要在过滤器中使用自动装配。所以我用@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批注,它将仅调用一次。
然后我在Spring Boot主类中添加以下内容作为修复。然后,我在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错误
我该如何解决在Spring过滤器中可以使用@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; } }
删除您的FilterRegistrationBean并TokenAuthorizationFilter在您的内部初始化,SecurityConfig如下所示:
FilterRegistrationBean
TokenAuthorizationFilter
SecurityConfig
@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使用构造函数注入进行设置:
@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 } }