Spring 安全忽略 url 不适用于我们的安全忽略方法 [重复]

Posted

技术标签:

【中文标题】Spring 安全忽略 url 不适用于我们的安全忽略方法 [重复]【英文标题】:Spring security ignore url does not work with the we security ignore method [duplicate] 【发布时间】:2021-04-02 21:01:20 【问题描述】:

我们正面临 SpringSecurity 忽略方法的问题。我们尝试跳过一些 url(执行器/健康)和资源的身份验证。身份验证在外部进行,我们有一个自定义过滤器来提取授权原则。

我们重写配置的方法如下所示:

public void configure(WebSecurity web) throws Exception 
        web.ignoring().antMatchers("/resources/**", "/actuator/health");

protected void configure(HttpSecurity http) throws Exception 
         http.addFilter(cutstomFilter).authorizeRequests()
        .antMatchers("/add","/update","/upload").hasAuthority("ADMIN").anyRequest().authenticated()
        .and().logout().logoutSuccessUrl("/logoutUser").and()
        .exceptionHandling().accessDeniedPage("/accessDenied").and().csrf().disable();
    

通过给定的实现,我们的 customFilter 被调用资源和健康 url。由于原理更改,这导致重新验证。

我们尝试添加此代码,但 customFilter 也被调用以获取健康 url。

http.authorizeRequests().antMatchers("/actuator/health").permitAll() 

注意:检查了@Rob Winch 的答案,但不明白如果我们将这些 url 放在忽略列表中,为什么我们需要自定义文件管理器。 https://***.com/a/19985323/2138633

【问题讨论】:

显示您的过滤器类别。可能是***.com/questions/39314176/…的重复 为了清楚起见,您的第一个安全配置是正确的。您的问题是您的过滤器不仅用作安全链过滤器,还用作 servlet 过滤器。如果您公开过滤器,Spring Boot 会自动执行此操作。 @dur:谢谢,我学到了一些关于安全配置中过滤器的新知识。 BR 在 Spring Boot 中添加自定义安全过滤器的代码示例:***.com/questions/24364436(为应用程序中的每个自定义安全过滤器添加一个 FilterRegistrationBean)。添加注释的请求正在等待处理以使其更容易,请参阅github.com/spring-projects/spring-boot/issues/16500。 【参考方案1】:

更新:请参阅@dur 的相关评论,它可能会在不进行重大更改的情况下解决问题。

To make it clear, your first security configuration is correct. Your problem 
is that your filter is used as a servlet filter not only as a security chain 
filter. Spring Boot does this autmatically, if you expose your filter.

https://***.com/a/39314867/14072498


OP 提到涉及到执行器端点。让我们看一下文档: https://spring.io/guides/topicals/spring-security-architecture

文档说:

If you want your application security rules to apply to the actuator 
endpoints, you can add a filter chain that is ordered earlier than the 
actuator one and that has a request matcher that includes all actuator 
endpoints.

Doc 建议将配置划分为WebSecurityConfigurerAdapter 的多个实现。

在下面的示例配置中,您应该将您称为自定义过滤器的内容应用于MainAppConfigurerAdapter

“多重Spring Boot安全配置”示例: https://medium.com/@igor.bonny/multiple-spring-boot-security-configuration-c876f1b6061e

为了跳过其他端点的身份验证,添加

.and()
.authorizeRequests().anyRequest().permitAll();

到下面显示的应用链的末尾。

要验证安全设置,请为所有端​​点添加集成测试。

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration 

  @Configuration
  @Order(ManagementServerProperties.BASIC_AUTH_ORDER - 1)
  public class ActuatorConfigurerAdapter extends WebSecurityConfigurerAdapter 
    @Override
      protected void configure(HttpSecurity http) 
          http.antMatcher("/actuator/**")
          ...
      
  

  @Configuration
  @Order(SecurityProperties.DEFAULT_FILTER_ORDER)
  public class MainAppConfigurerAdapter extends WebSecurityConfigurerAdapter 
      @Override
      protected void configure(HttpSecurity http) 
          http.antMatcher("/api/**")
          ...
      
  

【讨论】:

@RoarS。我尝试了这种配置,但它不起作用,因为我们在授权请求之前添加过滤器以提取原则。所以忽略 url 应该可以跳过过滤器调用。 这种安全配置会使新路由默认不安全。通常最好使用 anyRequest().authenticated() 或 event anyRequest().denyAll() 以避免任何不必要的副作用。 @Raphael:您的说法是正确的(赞成您的评论);此示例中的配置要求指定所有需要安全的端点。通过适当的测试覆盖率,它应该不会产生任何问题。 BR【参考方案2】:

一种方法是在安全配置和从身份验证中提取主体的自定义过滤器中使用模式。你可以这样做:

    声明忽略模式:

     static final String[] IGNORE_PATTERNS = new String[]  "**/*.js", "**/*.css", "/resources/**";
    

    声明允许所有模式:

     static final String[] PERMIT_ALL_PATTERNS = new String[]  "/login", "/logout", "/health";
    

    WebSecurity 中使用被忽略的模式:

     web.ignoring().antMatchers(IGNORE_PATTERNS);
    

    HttpSecurity 中使用 permit-all 模式:

     http.authorizeRequests().antMatchers(PERMIT_ALL_PATTERNS).permitAll().anyRequest().authenticated().and() ...
    

    在您的过滤器中声明RequestMatcher

     List<RequestMatcher> matchers = new ArrayList<>();
     for (String pattern : IGNORE_PATTERNS) 
         matchers.add(new AntPathRequestMatcher(pattern));
     
     for (String pattern : PERMIT_ALL_PATTERNS) 
         matchers.add(new AntPathRequestMatcher(pattern));
     
    
     RequestMatcher ignoreRequestMatcher = new OrRequestMatcher(matchers);  
    

    在过滤器的doFilter方法中使用请求匹配器:

     if (ignoreRequestMatcher.matches((HttpServletRequest) request)) 
     /* skip this filter */
     chain.doFilter(request, response);
     return;   /* rest of the filter code below */
    

【讨论】:

【参考方案3】:

按照https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-endpoints-security,您应该:

添加到您的属性文件

management.endpoints.web.exposure.include=*

更新您的安全配置,使其看起来像

  @Configuration(proxyBeanMethods = false)
  public class ActuatorSecurity extends WebSecurityConfigurerAdapter 


  @Override
  protected void configure(HttpSecurity http) throws Exception 
      http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
          requests.anyRequest().permitAll());
      
  

【讨论】:

以上是关于Spring 安全忽略 url 不适用于我们的安全忽略方法 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Spring security permit all 不适用于多个 url

Spring 安全性不适用于 JBoss 应用程序服务器上的 Grails 项目

Spring - CORS 不适用于安全配置

Spring Boot Actuator Endpoints 安全性不适用于自定义 Spring Security 配置

Thymeleaf 安全不适用于 Spring Boot 1.3.5

在aws上忽略基于url到spring boot 2应用程序的黑客攻击是不是安全?