【问题标题】:Different authentication on GET and POSTGET 和 POST 的不同身份验证
【发布时间】:2021-11-10 00:46:50
【问题描述】:

我一直在关注一个弹簧安全示例,但我无法理解它。一个简单的 RestController 在 GetMapping("/hello") 上用 200 状态码回复你好。将其更改为 PostMapping 后,我会收到一个 401,用于发送相同的凭据。

似乎我在这里遗漏了一些基本的东西,因为我希望两个请求都返回 200 状态代码。

安全配置:

@Configuration
public class ProjectConfig extends WebSecurityConfigurerAdapter {

    @Override
    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager(
                List.of(
                        User.withUsername("john")
                                .password("12345")
                                .authorities("ROLE_ADMIN")
                                .build(),
                        User.withUsername("jane")
                                .password("12345")
                                .authorities("ROLE_MANAGER")
                                .build()
                )
        );
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic()
                .and()
                .authorizeRequests()
                .anyRequest()
                .hasRole("ADMIN");
    }
}

具有以下 get 映射的 RestController 对此调用返回 200:

curl -v -u john:12345 localhost:8080/hello

还有这个映射:

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello!";
    }
}

具有以下后映射的 RestController 对此调用返回 401:

curl -X POST -v -u john:12345 localhost:8080/hello

还有这个映射:

@RestController
public class HelloController {

    @PostMapping("/hello")
    public String hello() {
        return "Hello!";
    }
}

【问题讨论】:

    标签: spring-boot spring-security spring-security-rest


    【解决方案1】:

    正如@Matheus Cirillo 所指出的,CSRF protectionenabled by default

    我们很想禁用 CSRF 保护,因为我们使用的是 restful api,但是consider what happens 如果您使用基于浏览器的单页应用程序与服务器交互。相同的经过身份验证的会话在浏览器中仍然可用,并且应用程序仍然容易受到 CSRF 攻击。

    您可以在文档的您自己的应用程序中找到some examples of how to work with csrf protection。在restful api中,也可以在header或者response参数中provide an endpoint that returns the csrf token

    【讨论】:

      【解决方案2】:

      Spring 的 CSRF 保护在 Spring Security 中默认启用。 POST 请求受此行为影响。

      通过以下方式禁用它:

      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.csrf().disable();
      }
      

      【讨论】:

      • 请不要建议简单地禁用 CSRF。查看最近 SpringOne 会议上的 beginning of this video (3:40),了解执行此操作时会发生什么。
      • 我认为他没有推荐它,而是展示了手头问题的解决方案。但你是对的,绝对不是生产环境中的解决方案。我一直在关注这本书,后来出现了 csrf 的章节。
      • 哇,朋友们。实际上,我在没有任何解释的情况下发布这么小的答案是我的错误。我的意思只是试图快速“修复”OP 的问题。是的,我知道当你禁用 CSRF 时会发生什么。 @1174 如果您想将史蒂夫的答案标记为解决方案,那没问题。他的回答更完整,并发送了有关禁用 CSRF 的可能问题的参考,以及有关如何使用 Spring 的 CSRF 保护的参考。如果您想取消标记我的答案并标记史蒂夫的答案,没问题。
      猜你喜欢
      • 2012-02-03
      • 2012-10-14
      • 1970-01-01
      • 2015-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      相关资源
      最近更新 更多