Spring Security 多个 url 规则集不能一起工作

Jam*_*phy 1 java spring spring-security

我有一个 HTTP Spring Security 配置,当我注释掉每个单独的方面时它似乎可以工作,但是当我将 Spring Security 规则组合在一起时它不起作用,所以我知道问题不在于 theregexMatcher或 the,antMatcher而是应用了规则组合。

这是我的 Spring Security 课程:

package com.driver.website.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.csrf.CsrfTokenRepository;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
import org.springframework.security.web.header.writers.StaticHeadersWriter;
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import java.security.AccessControlContext;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${widget.headers.xframeoptions.domains.allowed}")
    private String allowedXFrameOptions;

    @Value("${widget.headers.origins.allowed}")
    private String allowedOrigins;

    @Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off

        http.exceptionHandling().accessDeniedPage("/login")
                .and()
                .formLogin().loginPage("/login").defaultSuccessUrl("/myaccount", true).permitAll()
                .and()
                .authorizeRequests()
                .antMatchers("/**").permitAll();

        http.regexMatcher("^((?!(/widget|/assistedSearch)).)*$")
                .headers().frameOptions().disable()
                .regexMatcher("^((?!(/widget|/assistedSearch)).)*$")
                .headers()
                .xssProtection()
                .contentTypeOptions()
                .addHeaderWriter(new StaticHeadersWriter("X-FRAME-OPTIONS", "SAMEORIGIN"));

        http.antMatcher("/widget")
            .headers()
            .frameOptions()
            .disable()
            .antMatcher("/widget")
            .headers()
            .addHeaderWriter(new StaticHeadersWriter("X-FRAME-OPTIONS", "ALLOW-FROM " + allowedXFrameOptions));

        http.requestMatchers().antMatchers("/assistedSearch", "/widget")
            .and()
            .headers()
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Origin", allowedOrigins))
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Methods", "GET, POST"))
            .addHeaderWriter(new StaticHeadersWriter("Access-Control-Allow-Headers", "Content-Type"));

        // @formatter:on
    }
}
Run Code Online (Sandbox Code Playgroud)

规则应该是...

  • 对于除 /widget 和 /assistantSearch 以外的所有 url,我们应该添加 SAMEORIGIN X-Frame-Options 标头
  • 对于/widget端点,我们应该添加 X-Frame-Options: ALLOW-FROM 标头
  • 对于/widget/assistedSearch端点,我们应该添加Access-Control-Allow-Origin,Access-Control-Allow-MethodsAccess-Control-Allow-Headers标头

正如我上面提到的,如果我注释掉For all urls规则集,那么其他两个将协同工作,但是如果没有注释规则,则For all urls不会出现任何标题。

有没有人知道为什么会这样?如何在 Spring Security 中添加多个规则集并用新规则覆盖现有规则集?

我试过

http.antMatcher("/widget")
    .headers()
    .frameOptions()
    .disable()
Run Code Online (Sandbox Code Playgroud)

这再次似乎可以单独工作,但不能组合使用。

提前致谢!

dur*_*dur 6

您覆盖了之前的匹配器,请参阅HttpSecurity.html#antMatcher

调用antMatcher(String)将覆盖以前调用mvcMatcher(String)}requestMatchers()antMatcher(String)regexMatcher(String),和requestMatcher(RequestMatcher)

HttpSecurity.html#regexMatcher

调用regexMatcher(String)将覆盖以前调用mvcMatcher(String)}requestMatchers()antMatcher(String)regexMatcher(String),和requestMatcher(RequestMatcher)

如果您想要多个配置HttpSecurity,请参阅Spring Security Reference

我们可以配置多个 HttpSecurity 实例,就像我们可以有多个<http>块一样。关键是WebSecurityConfigurationAdapter多次延长。例如,以下是对以 开头的 URL 进行不同配置的示例/api/

@EnableWebSecurity
public class MultiHttpSecurityConfig {
  @Autowired
  public void configureGlobal(AuthenticationManagerBuilder auth) { 1
      auth
          .inMemoryAuthentication()
              .withUser("user").password("password").roles("USER").and()
              .withUser("admin").password("password").roles("USER", "ADMIN");
  }

  @Configuration
  @Order(1)                                                        2
  public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
      protected void configure(HttpSecurity http) throws Exception {
          http
              .antMatcher("/api/**")                               3
              .authorizeRequests()
                  .anyRequest().hasRole("ADMIN")
                  .and()
              .httpBasic();
      }
  }

  @Configuration                                                   4
  public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
              .authorizeRequests()
                  .anyRequest().authenticated()
                  .and()
              .formLogin();
      }
  }
}
Run Code Online (Sandbox Code Playgroud)