I'm running a SpringBoot application with a the root class being annotated with @SpringBootApplication
, @EnableAutoConfiguration
.
I've created a UserRepositoryInterface
interface, which extends the CrudRepository
interface with my User JPA object. There is no implementation for this interface and there was no need for one yet. Neither are there any configuration files for anything in this Application. Except for the JPA DB connection, but that works.
public interface UsersRepositoryInterface extends CrudRepository<User, Long> {
// Query to search for users via email
List<User> findByEmail(@Param("email") String email);
}
And I've succesfully Autowired it into some REST endpoints. The problem appears, when I try to Autowire it into my security classes. I'm trying for authentication with JWT and it works. Now I want to call the database during the log-in process and I'm having an issue. Here are the classes:
First the WebSecurityConfiguererAdapter
class, where I add the paths to the filter. Note the line with "new JWTLoginFilter
", which is the class where I try to Autowire:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService userDetailsServ;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
//Allow options pre-flight request
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// Allow POST request to /login
.antMatchers(HttpMethod.POST, "/login").permitAll()
// Others must be authenticated
.anyRequest().authenticated()
.and()
// We filter the api/login requests
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// And filter other requests to check the presence of JWT in header
.addFilterBefore(new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Change logging in from username+password to email+password
auth.userDetailsService(userDetailsServ);
}
}
And the JWTLoginFilter
class. I ommited some irrelevant code:
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
@Autowired
private UsersRepositoryInterface userRepo;
public JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(
HttpServletRequest req, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
//Check if userRepo is injected
if(userRepo == null) {
System.out.println("Null");
}
AccountCredentials creds = new ObjectMapper()
.readValue(req.getInputStream(), AccountCredentials.class);
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
creds.getEmail(),
creds.getPassword(),
Collections.emptyList()
)
);
}
}
The println
in JWTLoginFilter
will always return Null, when called upon.
Am I missing something?
SOLVED IT:
Works now.
Annotated the JWTLoginFilter with
@Component("someName")
And injected it in the WebSecurityConfig with
@Resource(name="someName")
private JWTLoginFilter myFilter;
Hardcoded the URL in the JWTLoginFilter constructor, but I still had to Autowire the AuthenticationManager from the WebSecurityConfig into the JWTLoginFilter.
First had to make the AuthenticationManager a Bean. Used the answer here: How To Inject AuthenticationManager using Java Configuration in a Custom Filter
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
Then injected it with answer here: Spring Security authenticationmanager must be specified - for custom filter
@Override
@Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
While removing the
setAuthenticationManager(authManager);
in the constructor in JWTLoginFilter