Use AbstractAuthenticationProcessingFilter for multiple URLs

13,459

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/**")                                                                            
     ));
Share:
13,459

Related videos on Youtube

worldbeater
Author by

worldbeater

Updated on June 19, 2022

Comments

  • worldbeater
    worldbeater almost 2 years

    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.

  • worldbeater
    worldbeater over 6 years
    thanks a ton for the simplified explanation and your time. I think I have a more solidified understanding of it now.