有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring安全绕过URL或过滤器

我有一个Spring Boot应用程序,它只公开了一个REST API。我需要保护它,我正在使用一种基于令牌的方法——特别是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 Bootapplication.yml文件没有启用/修改任何安全相关功能的设置


共 (1) 个答案

  1. # 1 楼答案

    我做的和解决方案中提到的一样

        @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时,我得到:

    Security filter chain: [WebAsyncManagerIntegrationFilter
    SecurityContextPersistenceFilter
    HeaderWriterFilter
    CorsFilter
    LogoutFilter
    AuthTokenFilter
    RequestCacheAwareFilter
    SecurityContextHolderAwareRequestFilter
    AnonymousAuthenticationFilter
    SessionManagementFilter
    ExceptionTranslationFilter
    FilterSecurityInterceptor ]

    我该怎么解决这个问题