【问题标题】:Spring security not allowing access with simple matcher and permitAllSpring 安全性不允许使用简单的匹配器和 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);
  }

【问题讨论】:

    标签: java spring-boot spring-security


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2014-09-02
      • 2020-02-29
      • 2019-08-19
      • 1970-01-01
      • 2011-05-20
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多