Spring 安全性不允许使用简单的匹配器和 permitAll 进行访问

Posted

技术标签:

【中文标题】Spring 安全性不允许使用简单的匹配器和 permitAll 进行访问【英文标题】:Spring security not allowing access with simple matcher and permitAll 【发布时间】:2019-12-30 18:31:13 【问题描述】:

就 Spring 安全性而言,它对我来说是全新的。我在网上找到了许多描述如何设置基本安全性的资源,并且能够让 HTTPS REST 调用与服务器端的以下配置一起工作:

@Configuration
@EnableWebSecurity
@EnableConfigurationProperties(SecurityAuthProperties.class)
public class ServerSecurityConfiguration extends WebSecurityConfigurerAdapter 

  private final SecurityAuthProperties properties;

  @Autowired
  public ServerSecurityConfiguration(SecurityAuthProperties properties) 
    this.properties = properties;
  

  @Override
  public void configure(HttpSecurity http) throws Exception 
    properties.getEndpoints().forEach((key, value) -> 
      try 
        for (HttpMethod method : value.getMethods()) 
          http.authorizeRequests().antMatchers(method, value.getPath()).permitAll().and()
              .httpBasic().and().csrf().disable();
        
       catch (Exception e) 
        throw new SecurityConfigurationException(
            "Problem encountered while setting up endpoint restrictions", e);
      
    );

    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  


不过,经过仔细检查,似乎某些部分(不确定有多少)实际上被禁用了。这可能是它允许从客户端访问的原因吗?

当我将配置修改为以下内容时,我总是得到响应“禁止”。

  @Override
  public void configure(HttpSecurity http) throws Exception 
    http.authorizeRequests().antMatchers("/rst/**").permitAll();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  

在我看来,这段代码将允许访问路径 /rst 及以下路径中的任何内容,但似乎恰恰相反。我错过了什么?

注意:我应该提到的另一件事是目前没有“用户”身份验证。 “客户端”不是基于 Web 的,而是一个单独的 Spring Boot 服务,具有自己的客户端安全配置。

更新

这是其中一个控制器:

@RestController
@RequestMapping("/rst/missionPlanning")
public class MissionPlannerController 

  @Autowired
  private MissionPlanner         service;
  @Autowired
  private ThreadPoolTaskExecutor executor;

  @PostMapping(value = "/planMission", produces = MediaType.APPLICATION_JSON_VALUE)
  public DeferredResult<ResponseEntity<GeneralResponse>> planMission() 
    DeferredResult<ResponseEntity<GeneralResponse>> result = new DeferredResult<>(60000L);
    executor.execute(new Runner(result));
    return result;
  

  private class Runner implements ITask 

    private DeferredResult<ResponseEntity<GeneralResponse>> result;

    public Runner(DeferredResult<ResponseEntity<GeneralResponse>> result) 
      this.result = result;
    

    @Override
    public void executeTask() 
      // Invoke service and set result.
      result.setResult(ResponseEntity.ok(service.planMission()));
    
  

更新

有趣。我从另一个 SO 帖子 (Security configuration with Spring-boot) 中找到了一个似乎有效的示例。唯一不同的是禁用 CSRF。

我看到它代表 Cross-Site Request Forgery,但我真的不明白那是什么,我是否应该启用它,如果我启用它,我该如何让它工作呢?

  @Override
  public void configure(HttpSecurity http) throws Exception 
    http.csrf().disable().authorizeRequests().antMatchers("/rst/**").permitAll();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
  

【问题讨论】:

【参考方案1】:

您设置控制器的方式可能有问题。包含该路径的控制器是否有@RequestMapping("/rst")

如果你用你的控制器的样子更新你的帖子会很有帮助。

编辑: 如果您必须禁用 CSRF,您的问题似乎是发出的请求类型。

CSRF 要求在所有可能导致更改的请求方法上指定一个令牌(即 POST、PUT、DELETE、PATCH,但不是 GET)。

这样做的原因是,当您控制网页时,它会增加一层安全性,只有您可以进行这些 API 调用。如果没有在请求中指定 CSRF 令牌,恶意用户将无法向您的服务发出该请求,因为 CSRF 令牌是无法猜测的。

您可以在此处阅读有关它的更多信息: https://docs.spring.io/spring-security/site/docs/3.2.0.CI-SNAPSHOT/reference/html/csrf.html#csrf-include-csrf-token

在这里:https://www.baeldung.com/spring-security-csrf

【讨论】:

以上是关于Spring 安全性不允许使用简单的匹配器和 permitAll 进行访问的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 安全配置忽略允许的端点

spring 中AOP 功能

Spring Security 和 Tomcat 8 JSessionId 响应不匹配

Spring Boot 安全性 - 允许使用过期 JWT 令牌的用户请求

Spring Security和Tomcat 8 JSessionId响应不匹配

Scala模式匹配错误,“错误的简单模式:错误使用_ *(不允许序列模式)”