我有一个具有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);
}
}