简体   繁体   中英

Spring Security intercept except annotated

Let's say I have a standard HttpSecurity protected endpoints, like:

http.csrf().disable().authorizeRequests().anyRequest().permitAll()

and validators on specific endpoints.

I got a request to make a new validator for most of our endpoints, but instead of adding an annotation everywhere I thought that it could be safer if I secure the endpoints like

http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().addFilterBefore(myGenericFilterBean, MyAuthenticationProcessingFilter.class)

(Given that MyGenericFilterBean is something extending GenericFilterBean)

but I want to make it skip this myGenericFilterBean for any endpoint I annotate with an annotation I would create for example @DontCheckMyFilter

Is it even possible without going way too far to make it worth it?

The best option in your case is use an specific path to avoid those endpoints, instead of a custom annotation. The reason is Spring filters provide a lot of functionality to work/deal with path and roles mainly.

So if you can change your approach, a possible solution could be:

@Component
public class MyGenericFilterBean extends OncePerRequestFilter {

  @Override
  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    // Do here what you need

    filterChain.doFilter(request, response);
  }

  // Method you should overwrite to avoid the execution of this filter   
  @Override
  protected boolean shouldNotFilter(HttpServletRequest request) {
    Set<String> avoidFilterForUrls = new HashSet<>(Arrays.asList("/no-filter/**"));
    AntPathMatcher pathMatcher = new AntPathMatcher();
    return avoidFilterForUrls.stream().anyMatch(p -> pathMatcher.match(p, request.getServletPath()));
  }

}

In the above example, the filter won't be executed (really doFilterInternal won't be invoked) for the requests with Urls started with /no-filter .

At this point, you need to take into account configure your security options correctly. Follow your example:

 http.csrf().disable()
            .authorizeRequests()
            // List of services do not require authentication
            //.antMatchers(GET, "/no-filter/**").permitAll()
            // Any other request must be authenticated
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(myGenericFilterBean, MyAuthenticationProcessingFilter.class)

Customizing shouldNotFilter the filter won't be executed but, taking into account you "are talking" about MyAuthenticationProcessingFilter , probably will be necessary to include those endpoints into the "whitelist" too, as you can see in:

// List of services do not require authentication
// Uncomment and customize with your own ones
//.antMatchers(GET, "/no-filter/**").permitAll()

Because if you have included a "role based security" or any other one in those endpoints, you need to remove it because Spring still verifies the security for them. I mean, if you don't want to apply MyAuthenticationProcessingFilter to those endpoints, no Spring security functionality should be included for them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM