How to apply spring security filter only on secure

2019-01-17 22:09发布

问题:

I have the following Spring Security configuration:

    httpSecurity
            .csrf()
            .disable()
            .exceptionHandling()
            .authenticationEntryPoint(unauthorizedHandler)
            .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/api/**").fullyAuthenticated()
            .and()
            .addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class);

The authenticationTokenFilterBean() is applied even on endpoints that do not match /api/** expression. I also tried adding the following configuration code

@Override
public void configure(WebSecurity webSecurity) {
    webSecurity.ignoring().antMatchers("/some_endpoint");
}

but this still did not solve my problem. How can I tell spring security to apply filters only on endpoints that match the secured URI expression? Thank you

回答1:

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.



回答2:

To bypass spring security for some specific endpoints do the following:

httpSecurity
     .authorizeRequests()
     .antMatchers("/some_endpoints").permitAll()
     .anyRequest().authenticated()
     .and()
     ...


回答3:

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