Search code examples
tokenaccess-tokenrestful-authenticationrestful-architecture

RESTful Authorization check


I have a RESTful web application, would like to implement a token based authentication. I was able to issue a token intercepting a request with a filter class as follows:

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    JpaConfiguration jpaConfiguration;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // disable caching
        http.headers().cacheControl();          
        http.csrf().disable() // disable csrf for our requests.
            .authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers(HttpMethod.POST, "/login").permitAll()
            .anyRequest().authenticated()
            .and()
            // Here the login requests is filtered
            .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()), UsernamePasswordAuthenticationFilter.class)
            // Much probably here I have to filter other requests to check the presence of JWT in header,
            // here i just add a commented block with teh name of the Filter
                //.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                ;
            }
    }

The JWTLoginFilter class looks like this:

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

    private TokenAuthenticationService tokenAuthenticationService;
public JWTLoginFilter(String url, AuthenticationManager authenticationManager) {
     super(new AntPathRequestMatcher(url));
     setAuthenticationManager(authenticationManager);
     tokenAuthenticationService = new TokenAuthenticationService();
}

 @Override
 public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
 throws AuthenticationException, IOException, ServletException {
     ServletInputStream inputStream = httpServletRequest.getInputStream();
     httpServletRequest.getCharacterEncoding();

     ObjectMapper mapper = new ObjectMapper();
     AccountCredentials credentials = mapper.readValue(inputStream, AccountCredentials.class);

     UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword());
     return getAuthenticationManager().authenticate(token);
 }
 @Override
 protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication)
 throws IOException, ServletException {
     String name = authentication.getName();
     tokenAuthenticationService.addAuthentication(response, name);
     }
}

Which class should extend the JWTAuthenticationFilter in order to intercept the request?

Is it still the AbstractAuthenticationProcessingFilter class?

Is there a better way to develop token based authentication?


Solution

  • So I finally find a solution:

    public class JWTAuthenticationFilter extends GenericFilterBean implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            try{
                ...
    
                SecurityContextHolder.getContext().setAuthentication(token);
                chain.doFilter(servletRequest, response);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    

    The JWTAuthenticationFilter extends a GenericFilterBean class and must implement a spring security Filter, the method doFilter does the trick.

    NOTE: you have to call the doFilter method from FilterChain class otherwhise you newer come to the endpoint, I got crazy on that.