【问题标题】:Spring Security not intercepting correctly? [duplicate]Spring Security 没有正确拦截? [复制]
【发布时间】:2020-03-11 19:43:35
【问题描述】:

我的 Spring Boot 配置如下所示:

http
    .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
    .addFilterBefore( new Filter(), UsernamePasswordAuthenticationFilter.class)
    .csrf().disable() // Disabled, cause enabling it will cause sessions
    .headers()
        .frameOptions()
        .sameOrigin()
        .addHeaderWriter(new XXssProtectionHeaderWriter())
        .and()
    .authorizeRequests()
        .antMatchers("/app/**", "/rest/**").hasAuthority(DefaultPrivileges.ACCESS_TASK)
        .anyRequest().permitAll();

我的理解是只有以/app/rest 开头的请求会被我的自定义过滤器拦截,但事实证明对根 (http://localhost:8080/context/) 的请求也会被拦截。

我有多个 Spring Security 配置,其他配置如下所示:

http
    .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
    .csrf().disable();

if (taskAppProperties.isRestEnabled()) {
    if (restAppProperties.isVerifyRestApiPrivilege()) {
        http
            .antMatcher("/*-api/**")
            .authorizeRequests()
                .antMatchers("/*-api/**").hasAuthority(DefaultPrivileges.ACCESS_REST_API)
                .and()
            .httpBasic();
    } else {
        http
            .antMatcher("/*-api/**")
            .authorizeRequests()
                .antMatchers("/*-api/**").authenticated()
                .and()
            .httpBasic();
    }
} else {
    http
        .antMatcher("/*-api/**")
        .authorizeRequests()
            .antMatchers("/*-api/**").denyAll();
}

谁能帮忙?

【问题讨论】:

  • http.authorizeRequests() 表示http.antMatcher("/**").authorizeRequests()。这意味着所有 url 都将被拦截并验证授权。如果您希望您的 http 安全配置仅限于极少数 URL 集,那么您应该选择 http.antMatcher("/app/**", "/rest/**").authorizeRequests() 或者在高级中您可以选择 this link 中给出的 requestMatcher

标签: spring spring-boot spring-security


【解决方案1】:

我意识到这有点令人困惑,但实际上有 两个 antMatchers 方法,一个从 authorizedRequests 分支,另一个从 requestMatchers 分支。

让我们看看下面的声明:

http
    .requestMatchers()
        .antMatchers("/app/**", "/api/**")
        .and()
    .authorizeRequests()
        .antMatchers("...").authenticated()
    ...

requestMatchers() DSL 用于描述与 Spring Security 过滤器链实例相关的端点。因此,此过滤器链仅适用于以 /app/api 开头的 URI。

我们再来看看另一个:

http
    .authorizeRequests()
    .antMatchers("/app/**", "/api/**")
    .authenticated();

虽然这似乎在做同样的事情,但事实并非如此。那是因为您正在调用属于authorizeRequests()antMatchers 方法。

这就是indentation is important with the Spring Security DSL 的原因。因为 DSL 中有一个层次结构,所以你想缩进,就像你想在 if 语句中缩进一样。

在 Spring Security 5.2 中,使用新的 lambda DSL 对此进行了一些简化:

http
    .requestMatchers(r -> r.antMatchers("/app/**", "/api/**"))
    .authorizeRequests(a -> a.antMatchers("...").authenticated());

【讨论】:

    【解决方案2】:

    HttpSecurity.authorizeRequests - 返回ExpressionInterceptUrlRegistry,我们在其中设置匹配器和角色条件,这将使用方法ExpressionInterceptUrlRegistry.getRegistry 添加,如果您仅在发生实际身份验证的permitAll 存根处检查此方法的其他用法。

    我们使用HttpSecurity.addFilterBefore 添加的过滤器不会检查任何请求匹配。如果需要,您可以在自定义过滤器中再检查一次以避免其他 URI

    http
      .sessionManagement()
      .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
      .and()
      .addFilterAfter( new Filter() {
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
    
          }
    
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
              if(httpServletRequest.getRequestURI().startsWith("/app/") || httpServletRequest.getRequestURI().startsWith("/rest/")) {
                  // Do you secured filter computations
    
              } 
              chain.doFilter(request, response);
          }
    
          @Override
          public void destroy() {
    
          }}, UsernamePasswordAuthenticationFilter.class)
      .csrf()
      .disable() // Disabled, cause enabling it will cause sessions
      .headers()
      .frameOptions()
      .sameOrigin()
      .addHeaderWriter(new XXssProtectionHeaderWriter())
      .and()
      .authorizeRequests()
      .antMatchers("/app/**", "/rest/**")
      .hasAuthority(DefaultPrivileges.ACCESS_TASK)
      .anyRequest()
      .permitAll();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-24
      • 2012-08-15
      • 2014-06-17
      • 2013-03-17
      • 2013-06-04
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      相关资源
      最近更新 更多