英文:
java.lang.IllegalArgumentException: Cannot register after unregistered Filter class
问题
@Component
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private Jwtutil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwt);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
@EnableWebSecurity
public class SecurityConfigureAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService myUseserDeatailService;
@Autowired
private JwtFilter jwtRequestFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUseserDeatailService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/authentication").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, JwtFilter.class).authorizeRequests();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
英文:
I am developing login service using spring boo. when developing it I got below error and the class
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.jwt.logincservice.filter.JwtFilter
@Component
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
private Jwtutil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
username = jwtUtil.extractUsername(jwt);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
WebSecurityConfigurerAdapter class
@EnableWebSecurity
public class SecurityConfigureAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailsService myUseserDeatailService;
@Autowired
private JwtFilter jwtRequestFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUseserDeatailService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests().antMatchers("/authentication").permitAll()
.anyRequest().authenticated()
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtRequestFilter, JwtFilter.class).authorizeRequests();
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
答案1
得分: 10
你正在尝试在 JwtFilter.class
之前添加 jwtRequestFilter
,这有点像是在告诉 Spring Security 在自身之前放置自己。
你可以尝试将这行代码更改为:
http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class).authorizeRequests();
此外,Spring Boot 中的每个 Filter
bean 也会自动添加到默认的 servlet filter 链中,因此在初始化后,它将出现两次:
- 作为 servlet 过滤器在您的链中
- 作为 SpringSecurityFilterChain 中的过滤器
如果您只想将其用作 Spring Security 过滤器,请删除 @Component
注解,并在将其添加到 springSecurityFilterChain 之前自行实例化:
http.addFilterBefore(new JwtFilter(), UsernamePasswordAuthenticationFilter.class).authorizeRequests();
英文:
you are trying to add the jwtRequestFilter
before the JwtFilter.class
which is kind of telling spring security to put itself before itself.
can you try changing this line to:
http.addFilterBefore(jwtRequestFilter,UsernamePasswordAuthenticationFilter.class).authorizeRequests();
additionally, every Filter
bean in spring boot is automatically added also to your default servlet filter chain, so after initialization, it will be present twice:
- as a Servlet Filter in your chain
- as a Filter in your springSecurityFilterChain
if you just want to use it as a spring security filter remove the @Component
annotation and instantiate it by yourself before adding it to the springSecurityFilterChain:
http.addFilterBefore(new JwtFilter(),UsernamePasswordAuthenticationFilter.class).authorizeRequests();
答案2
得分: 0
如果您正在使用Java配置进行Bean配置,则必须在WebInitializer类中注册您的过滤器bean。
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// 您的配置
@Override
protected Filter[] getServletFilters() {
DelegatingFilterProxy filterProxy = new DelegatingFilterProxy();
filterProxy.setTargetBeanName("jwtFilter");
return new Filter[]{filterProxy};
}
}
英文:
If you are using java config for bean configuration you have to register your filter bean in WebInitializer class.
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
//your configs
@Override
protected Filter[] getServletFilters() {
DelegatingFilterProxy filterProxy = new DelegatingFilterProxy();
filterProxy.setTargetBeanName("jwtFilter");
return new Filter[]{filterProxy};
}
}
答案3
得分: 0
*class 部分要放置的过滤器列表可以通过增加 Spring Security 的调试级别来检索。那里的任何过滤器都将起作用。
英文:
The list of filters to put in the *class part can be retrieved by increasing the debug level on spring security. Any filters there will work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论