Cannot pass AuthenticationManager to custom filter by @Autowired
我正在尝试通过@Autowired注释将过滤器JWTLoginFilter传递给WebSecurityConfig WebSecurityConfigurerAdapter。当JWTLoginFilter尝试从WebSecurityConfig获取AuthenticationManager时出现问题。
启动服务器时,出现以下错误:
Description:
The dependencies of some of the beans in the application context form
a cycle:JWTLoginFilter defined in file
[C:\\Users\\user\\workspace\\backend\\target\\classes\\pl\\dn\\schoolsystem\\service\\jwt\\JWTLoginFilter.class]webSecurityConfig (field
pl.dn.schoolsystem.service.jwt.JWTLoginFilter
pl.dn.schoolsystem.config.WebSecurityConfig.jwtLoginFilter)
错误图片
我认为这种循环依赖注入。我对此卡住了,我不知道如何解决。
WebSecurityConfig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private Environment env; @Autowired private UserSecurityService userSecurityService; @Autowired JWTLoginFilter jwtLoginFilter; private static final String Salt ="salt"; // should be protected better @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(12, new SecureRandom(Salt.getBytes())); } @Bean(name = BeanIds.AUTHENTICATION_MANAGER) @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(). authorizeRequests().antMatchers("/").permitAll() .antMatchers(HttpMethod.POST,"/login").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() //.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), //UsernamePasswordAuthenticationFilter.class) .addFilterBefore(jwtLoginFilter, UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder()); } } |
JWTLoginFilter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | @Component public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter{ @Autowired UserService userService; @Autowired public JWTLoginFilter(@Value("/login") String url, AuthenticationManager authManager) { super(new AntPathRequestMatcher(url)); setAuthenticationManager(authManager); } @Override public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException, IOException, ServletException { System.out.println("Jestem w JwtLogginFilter.attemptAuthentication -------------------------------------"); AccountCredentials creds = new ObjectMapper() .readValue(req.getInputStream(), AccountCredentials.class); User user = userService.findByUsername(creds.getUsername()); return getAuthenticationManager().authenticate( new UsernamePasswordAuthenticationToken( creds.getUsername(), creds.getPassword(), user.getAuthorities() ) ); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { System.out.println("Jestem w JWTLogginFilter.successfulAuthentication --------------------------------------"); System.out.println("authResult.getName():" + authResult.getName()); TokenAuthenticationService.addAuthentication(response, authResult.getName()); } } |
我正在使用Spring Boot 1.5.4。感谢您的建议
您的
从
1 2 3 4 | @Bean public JWTLoginFilter jwtLoginFilter() { return new JWTLoginFilter("/login", authenticationManager()); } |
您可能还需要在此方法中手动注入
感谢您的帮助Roman Puchkovskiy我可以更正我的代码。我的代码的最终结果:
WebSecurityConfig:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private Environment env; @Autowired private UserSecurityService userSecurityService; private static final String Salt ="salt"; // should be protected better @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(12, new SecureRandom(Salt.getBytes())); } @Bean public JWTLoginFilter jwtLoginFilter() throws Exception { return new JWTLoginFilter("/login", authenticationManager()); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(). authorizeRequests().antMatchers("/").permitAll() .antMatchers(HttpMethod.POST,"/login").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated() .and() // .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), // UsernamePasswordAuthenticationFilter.class) .addFilterBefore(jwtLoginFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userSecurityService).passwordEncoder(passwordEncoder()); } } |
JWTLoginFilter:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter{ @Autowired UserService userService; public JWTLoginFilter(String url, AuthenticationManager authManager) { super(new AntPathRequestMatcher(url)); setAuthenticationManager(authManager); } @Override public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException, IOException, ServletException { System.out.println("Jestem w JwtLogginFilter.attemptAuthentication -------------------------------------"); AccountCredentials creds = new ObjectMapper() .readValue(req.getInputStream(), AccountCredentials.class); User user = userService.findByUsername(creds.getUsername()); return getAuthenticationManager().authenticate( new UsernamePasswordAuthenticationToken( creds.getUsername(), creds.getPassword(), user.getAuthorities() ) ); } @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { System.out.println("Jestem w JWTLogginFilter.successfulAuthentication --------------------------------------"); System.out.println("authResult.getName():" + authResult.getName()); TokenAuthenticationService.addAuthentication(response, authResult); } } |