Spring Security绕过URL或过滤器

时间:2016-03-09 15:59:00

标签: java spring-security spring-boot

我有一个只暴露REST API的Spring Boot应用程序。我需要保护它并且我使用基于令牌的方法 - 特别是JWT。

到目前为止,这是我实施的内容:

//
// The Spring Security configuration class
@EnableGlobalAuthentication
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  @Override
  protected void configure(final HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests()
          .antMatchers("/api/login", "/api/logout").permitAll()
          .antMatchers("/api/**").authenticated()
          .anyRequest().authenticated()
        .and()
          .addFilterBefore(new JwtFilter(), BasicAuthenticationFilter.class)
          .sessionManagement()
          .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  }
}
//
// The JWT filter class to check for the token in the HTTP request (headers)
public final class JwtFilter extends GenericFilterBean {
  private final Logger logger = LoggerFactory.getLogger(this.getClass());

  @Override
  public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws
      IOException, ServletException {
    final HttpServletRequest req = (HttpServletRequest)request;
    final String header = req.getHeader("Authorization");

    logger.debug("{} {}", req.getMethod(), req.getRequestURI());
    if ((null == header) || !header.startsWith("Bearer ")) {
      logger.debug("Missing or invalid Authorization header");
    }
    try {
      // Check the token here; the implementation is not relevant here
      /*SecurityContextHolder.getContext()
          .setAuthentication(manager.authenticate(new JwtToken(JWTParser.parse(header.substring(7)))));*/
      chain.doFilter(request, response);
    } catch (final AuthenticationException e) {
      SecurityContextHolder.clearContext();
      // Do some other stuff here
    } catch (final ParseException e) { /* ... */ }
  }
}

问题是过滤器对每个URI都正确执行,但我希望能够从同一个集合中排除某些端点。我的API位于此上下文/api/*中,我想排除/api/login/api/logout

注意:我的Spring Boot application.yml文件没有启用/修改任何与安全相关的功能的设置。

2 个答案:

答案 0 :(得分:10)

将对通过HttpSecurity配置的所有端点执行过滤器。如果您不希望对某些端点应用过滤器,请将它们包含在配置WebSecurity的方法中。例如,

@Override
public void configure(WebSecurity web) throws Exception {
    web
      .ignoring()
        .antMatchers("/api/login", "/api/logout");
}

请阅读this post了解详情。

答案 1 :(得分:0)

我正在执行解决方案中提到的

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
        .and().csrf().ignoringAntMatchers("/api/auth/**").disable()
        .exceptionHandling().authenticationEntryPoint(unauthorizedHandler)
        .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and().authorizeRequests()
        .antMatchers("api/content/**").permitAll()
        .anyRequest().authenticated();
        
        http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("api/auth/signup");
    }

每个注册请求仍然会使用doFilterInternal()方法,这是一个自定义方法。

在调试模式下运行EnableWebSecurity时,我得到了:

安全过滤器链: [WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
LogoutFilter
AuthTokenFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor]

我应该怎么做才能解决这个问题?