Spring JWT Filter Configuration

Viewed 2147

I want to add a Filter to authenticate users with token. I achieve this by adding two filters:

public class JwtFilter extends GenericFilterBean {

private TokenAuthenticationService authenticationService;

public JwtFilter(TokenAuthenticationService service) {
    this.authenticationService = service;
}

public JwtFilter() {
}

@Override
public void doFilter(final ServletRequest request,
                     final ServletResponse response,
                     final FilterChain chain) throws IOException, ServletException {
    System.out.println("JwtFilter.doFilter");
    SecurityContextHolder.getContext().setAuthentication(
            authenticationService.getAuthentication((HttpServletRequest) request));
    chain.doFilter(request, response);
}

After that I created the second Filter, to authorise users:

public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter {


private final TokenAuthenticationService tokenAuthenticationService;
private final UserDetailsService userService;

public StatelessLoginFilter(String urlMapping, TokenAuthenticationService tokenAuthenticationService,
                            UserDetailsService userDetailsService, AuthenticationManager authManager) {
    super(new AntPathRequestMatcher(urlMapping));
    this.userService = userDetailsService;
    this.tokenAuthenticationService = tokenAuthenticationService;
    setAuthenticationManager(authManager);
}

@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
    System.out.println("StatelessLoginFilter.successfulAuthentication");
    // Lookup the complete User object from the database and create an Authentication for it
    final User authenticatedUser = (User) userService.loadUserByUsername(authResult.getName());
    final UserAuthentication userAuthentication = new UserAuthentication(authenticatedUser);

    // Add the custom token as HTTP header to the response
    tokenAuthenticationService.addAuthentication(response, userAuthentication);

    // Add the authentication to the Security context
    SecurityContextHolder.getContext().setAuthentication(userAuthentication);
}

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException {
    System.out.println("StatelessLoginFilter.attemptAuthentication");
    final User user = new ObjectMapper().readValue(request.getInputStream(), User.class);
    final UsernamePasswordAuthenticationToken loginToken = new U

sernamePasswordAuthenticationToken(
                user.getUsername(), user.getPassword());
        return getAuthenticationManager().authenticate(loginToken);
   }
}

And here is my SecurityConfiguration:

    @Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private TokenAuthenticationService tokenAuthenticationService;



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http    .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

                .authorizeRequests()
                .antMatchers("/user/**").authenticated()
                .anyRequest().permitAll().and()
                .addFilterBefore(new StatelessLoginFilter("/login", tokenAuthenticationService, userDetailsService, authenticationManager()), UsernamePasswordAuthenticationFilter.class)
                .addFilterBefore(new JwtFilter(tokenAuthenticationService), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
     auth .inMemoryAuthentication()
                .withUser("user").password("password").roles("USER");
    }

    @Override
    protected UserDetailsService userDetailsService() {
        return userDetailsService;
    }

}

Now, when I send request to "/login" I get 404 error page. Trully, I don't have Controller mapped, but in security there is a url mapping in security config. As I've read in docs :

Creates a matcher with the specific pattern which will match all HTTP methods in a case insensitive manner.

Also, you can see System.out.println() lines.I put breakpoint here, but execution doesn't reach this lines. I'm not sure if I registered this filters properly. My code mostly base on this repository:https://github.com/BranislavLazic/angular-security

1 Answers
Related