Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use AbstractAuthenticationProcessingFilter for multiple URLs

I have the below endpoint patterns in my application

  1. /token -- accessible to all
  2. /rest/securedone/** -- requires authentication
  3. /rest/securedtwo/** -- requires authentication
  4. /rest/unsecured/** -- does not require authentication

As of now, I am able to access the /token endpoint. But /rest/securedone/** and /rest/unsecured/** return 401 when a token(JWT) is not sent. It is my intention to secure /rest/securedone/** and that is fine /rest/unsecured/** should be accessible.

My httpSecurity config is as below:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .cors()
            .and()
            .csrf().disable()
            .authorizeRequests()
                .antMatchers("/token").permitAll()
                .antMatchers("/rest/secured/**").authenticated()
            .and()
            .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
            .and()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    http.addFilterBefore(authenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);

    http.headers().cacheControl();
}

and my AbstractAuthenticationProcessingFilter extended class is as below:

public class MyAuthenticationTokenFilter extends AbstractAuthenticationProcessingFilter {

    private static Logger log = LoggerFactory.getLogger(MyAuthenticationTokenFilter.class);

    public MyAuthenticationTokenFilter() { super("/rest/**");  }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws AuthenticationException, ServletException {
        //authentication handling code
    }


    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authResult);
        chain.doFilter(request, response);
    }
}

Can someone please help my figure out the below:

  1. When is the MyAuthenticationTokenFilter used? For which URL will it be invoked? How come, /rest/unsecured/** is also expecting authentication? It happens even if i explicitly say .antMatchers("/rest/secured/**").permitAll().

  2. Can I specify multiple url patterns in my super(defaultFilterProcessingUrl) call inside MyAuthenticationTokenFilter constructor? For example, if I have another url such as /api/secured/**, how can I get my MyAuthenticationTokenFilter to be invoked for /api/secured/** requests? I do not need different authentication handling so I want to re-use this filter.

like image 448
worldbeater Avatar asked Dec 13 '22 20:12

worldbeater


1 Answers

When is the MyAuthenticationTokenFilter used ?

This filter is using for processing the request with client credential,it will filter the url when the RequestMatcher match the request url, for example, in your configuration, it will handle the url that matches /rest/**, and try to convert the client credential to Authentication(e.g userInfo, role ...), it maybe throws an exception when the request with incorrect client credential. It is different to authorizeRequests(xxx.authenticated() or xxx.permit()), authorizeRequests just check the whether the authentication has some special attributes (e.g role, scope).

By way of analogy, AbstractAuthenticationProcessingFilter just puts some cards(Authentication) into a box(SecurityContext) by different clients, authorizeRequests just check the box has the card that it needed, or it will deny the request. AbstractAuthenticationProcessingFilter don't care who/how to use the cards, and authorizeRequests don't care where the cards come from.

Can I specify multiple url patterns in my super(defaultFilterProcessingUrl) call inside MyAuthenticationTokenFilter constructor ?

Yes, you can set the requiresAuthenticationRequestMatcher by setRequiresAuthenticationRequestMatcher, it will override the old requiresAuthenticationRequestMatcher, for example,

authenticationTokenFilter
    .setRequiresAuthenticationRequestMatcher(new OrRequestMatcher(                                                                                     
        new AntPathRequestMatcher("/rest/secured/**")                                                                                   
        , new AntPathRequestMatcher("/api/secured/**")                                                                            
     ));
like image 94
chaoluo Avatar answered Feb 13 '23 22:02

chaoluo