I\'m trying pass filter JWTLoginFilter to WebSecurityConfig WebSecurityConfigurerAdapter by @Autowired annotation. The problem arise when JWTLoginFilter try get AuthenticationMa
Your WebSecurityConfig
explicitly requests JWTLoginFilter
to be injected in it, and JWTLoginFilter
requests AuthenticationManager
to be injected in its constructor. AuthenticationManager
is supplied by WebSecurityConfig
, so you have a circular dependency.
Remove @Component
annotation from JWTLoginFilter
and define the filter as a bean in WebSecurityConfig
:
@Bean
public JWTLoginFilter jwtLoginFilter() {
return new JWTLoginFilter("/login", authenticationManager());
}
You will probably also need to inject UserService
manually in this method (for example, via constructor).
Thanks for help Roman Puchkovskiy I can correct my code. Final result of my code:
WebSecurityConfig:
@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:
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);
}
}