SpringBoot Spring Security不能将给定的过滤器仅应用于一个路径

时间:2019-02-06 13:37:17

标签: spring-boot spring-security

我有一个具有Spring安全性的SpringBoot应用程序。 对于执行器,我们有两条路径:/ actuator / **,对于特定的API,一条路径:/ api / v1 / mail/**。

我只想在向/ api / v1 / mail / something发出请求时应用过滤器(ApiKeyFilter),而 / actuator / something被调用时不应用!

我的配置如下:

@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Configuration
    @Order(1)
    public static class ActuatorsConfigurator extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
           http.antMatcher("/actuator/**").authorizeRequests().anyRequest().permitAll();
        }
    }

    @Configuration
    @Order(2)
    public static class ApiConfigurator extends WebSecurityConfigurerAdapter {

        @Autowired
        private ApiKeyFilter filter;

        private static final RequestMatcher PRIVATE_URLS = new AntPathRequestMatcher("/api/v1/mails/**");

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/api/**")
                .exceptionHandling()
                .defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PRIVATE_URLS)
                .and()
                .authorizeRequests()
                .antMatchers("/api/vi/mails/**")
                .authenticated()
                .and()
                .addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class)
                .csrf().disable().httpBasic().disable().formLogin().disable().logout().disable();
        }

        @Bean
        AuthenticationEntryPoint forbiddenEntryPoint() {
            return new HttpStatusEntryPoint(HttpStatus.FORBIDDEN);
        }
    }
   }

使用此代码,当调用/ actuator / health 时会调用我的过滤器(ApiKEyFilter),而在调用/ api / vi / mail / retrieve时会调用我的过滤器!

ApiKeyFilter:

@Component
public class ApiKeyFilter extends GenericFilterBean {

    private static final Logger LOGGER =    LoggerFactory.getLogger(ApiKeyFilter.class);

    private final String API_KEY = "ApiKey";

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        final String authParam = ofNullable(((HttpServletRequest) servletRequest).getHeader(HttpHeaders.AUTHORIZATION)).orElse(servletRequest.getParameter(API_KEY));

        final String token = ofNullable(authParam).map(value -> StringUtils.removeStart(value, API_KEY)).map(String::trim)
            .orElseThrow(() -> new BadCredentialsException("Missing api key"));
        LOGGER.debug(token);

       filterChain.doFilter(servletRequest, servletResponse);
    }
}

0 个答案:

没有答案