java Spring Security 绕过 URL 或过滤器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35896502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 00:43:36  来源:igfitidea点击:

Spring Security bypass URL or Filter

javaspring-securityspring-boot

提问by x80486

I have a Spring Boot application that is only exposing a REST API. I need to secure it and I'm using a token-based approach ― specifically JWT.

我有一个仅公开 REST API 的 Spring Boot 应用程序。我需要保护它,而且我正在使用基于令牌的方法——特别是 JWT。

So far, this is what I have implemented:

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

//
// 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) { /* ... */ }
  }
}

The issue is that the filter executes correctly for every single URI, but I want to be able to exclude some endpoints from the same set. My API is placed in this context /api/*and I want to exclude, for instance, /api/loginand /api/logout.

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

NOTE:My Spring Boot application.ymlfile doesn't have settings to enable/modify any security-related features.

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

回答by Pankaj

Filters will be executed for all the endpoints that are configured through HttpSecurity. If you do not want filters to be applied for certain endpoints, include them in a method that configures WebSecurity. For example,

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

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

Please read this postfor more details.

请阅读这篇文章了解更多详情。