How to apply spring security filter only on secured endpoints?

I have an application with the same requirement and to solve it I basically restricted Spring Security to a given ant match patter (using antMatcher) as follows:

http
    .antMatcher("/api/**")
    .authorizeRequests() //
        .anyRequest().authenticated() //
        .and()
    .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

You can read it as follows: for http only invoke these configurations on requests matching the ant pattern /api/** authorizing any request to authenticated users and add filter authenticationTokenFilterBean() before UsernamePasswordAuthenticationFilter. For all others requests this configuration has no effect.


My Requirement was to exclude the endpoint matching /api/auth/**, to achieve the same I have configured my WebSecurityConfig spring configuration component as follows:

/**
 * The purpose of this method is to exclude the URL's specific to Login, Swagger UI and static files.
 * Any URL that should be excluded from the Spring security chain should be added to the ignore list in this
 * method only
 */
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/api/auth/**","/v2/api-docs", 
            "/configuration/ui", 
            "/swagger-resources", 
            "/configuration/security",
            "/swagger-ui.html", 
            "/webjars/**",
            "/favicon.ico",
            "/**/*.png",
            "/**/*.gif",
            "/**/*.svg",
            "/**/*.jpg",
            "/**/*.html",
            "/**/*.css",
            "/**/*.js");
}


   /**
     * The purpose of this method is to define the HTTP configuration that defines how an HTTP request is 
     * going to be treated by the Spring Security chain. All the request URL's (excluding the URL's added
     * in WebSecurity configuration ignore list) matching this configuration have to pass through the
     * custom Spring security filter defined in this method
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
        .cors().disable()
        .authorizeRequests()
        .anyRequest()
        .authenticated()
        .and()
        .exceptionHandling()
        .authenticationEntryPoint(unauthorizedHandler)
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);
    }

/**
 * The purpose of this method is to create a new instance of JWTAuthenticationFilter
 * and return the same from the method body. It must be ensured that this filter should
 * not be configured as a Spring bean or registered into the Spring Application context
 * failing which the below filter shall be registered as a default web filter, and thus
 * all the URL's even the excluded ones shall be intercepted by the below filter
 */
public JWTAuthenticationFilter authenticationTokenFilterBean() {
    return new JWTAuthenticationFilter();
}

GenericFilterBean has a following method :

/**
     * Can be overridden in subclasses for custom filtering control,
     * returning {@code true} to avoid filtering of the given request.
     * <p>The default implementation always returns {@code false}.
     * @param request current HTTP request
     * @return whether the given request should <i>not</i> be filtered
     * @throws ServletException in case of errors
     */
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        return false;
    }

So in your filter that extends GenericFilterBean you can override that method and implement logic to run the filter only on the routes that you would like.


If you use the

.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

You can define in the constructor the specific path it will apply to:

public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super("/api/**");
        this.setAuthenticationManager(authenticationManager);
    }

    @Override
    protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
        return super.requiresAuthentication(request, response);
    }

The requiresAuthentication method will be used to know if that endpoint needs authentication.