【问题标题】:How to Solve 403 Error in Spring Boot Post Request如何解决 Spring Boot Post 请求中的 403 错误
【发布时间】:2018-11-02 07:43:29
【问题描述】:

我是 Spring Boot Rest 服务的新手。我使用 maven 项目在 spring boot 中开发了一些 rest api。

我已经成功开发了 GetPost Api。我的 GET 方法在邮递员和移动设备中正常工作。 当我尝试从邮递员发送 post 方法时,它可以正常工作,但从移动端发送 403 禁止错误。

这是我的配置:

spring.datasource.url = jdbc:mysql://localhost/sampledb?useSSL=false
spring.datasource.username = te
spring.datasource.password = test
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect
Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

请建议我如何解决错误。

【问题讨论】:

  • 您是否使用邮递员发送任何标题?我认为您正在发送令牌以验证请求。您是否通过移动设备在 POST 上发送此令牌?
  • 请添加您的 spring-boot 配置的详细信息。
  • 我只发送来自邮递员和手机@desoss的内容类型
  • 请附上日志,spring 在日志中有令人惊讶的可读错误消息;)
  • 这是我的配置:#spring.datasource.url = jdbc:mysql://192.168.4.2/maha?useSSL=false #spring.datasource.username = test #spring.datasource.password = test@123 # # ### Hibernate Properties ## SQL 方言使 Hibernate 为所选数据库生成更好的 SQL #spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect # ## Hibernate ddl auto (create ,创建删除,验证,更新)#spring.jpa.hibernate.ddl-auto = 更新@JannikWeichert

标签: spring rest maven spring-boot


【解决方案1】:

经过几个小时试图找到这个突然问题的原因,我发现我之前添加的注释

@JsonIgnore

到我的UserAccount 类的密码字段。

@JsonIgnore
String password

导致每个登录请求都失败,因为密码字段来自 PostMan 和我的 Angular 应用程序的 Null 字段。

删除 JsonIgnore 就行了。

你只需要找到另一种方法来隐藏你的密码。

【讨论】:

    【解决方案2】:

    我可以通过以下方式解决这个问题:

    <form th:action="@{url}" method="post">
    

    代替:

    <form action="url" method="post">
    

    th:action 标签似乎会重写 url 以启用 csrf 验证。

    【讨论】:

      【解决方案3】:

      在Spring Security中跨站检查默认是开启的,我们需要通过创建一个单独的类来禁用它来停止交叉检查。

      package com.baba.jaxws;
      
      import org.springframework.context.annotation.Configuration;
      import org.springframework.security.config.annotation.web.builders.HttpSecurity;
      import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
      
      @Configuration
      public class SecurityConfig extends WebSecurityConfigurerAdapter{
      
           @Override
          //we have stopped the csrf to make post method work
              protected void configure(HttpSecurity http) throws Exception{
                  http.cors().and().csrf().disable();
              }
      }
      

      【讨论】:

        【解决方案4】:

        在 Spring Security 中默认启用 CSRF。启用此功能可确保更改(对象)状态的 HTTP 请求出现 403 错误。 更多信息请访问:https://docs.spring.io/spring-security/site/docs/3.2.x/reference/htmlsingle/html5/#csrf

        可以在 Spring Security 中禁用 CSRF。但是,它默认启用(约定优于配置)并且有充分的理由。这也在提供给 Spring 的 Security 的链接中进行了解释。

        一个使用 Thymeleaf 的工作示例可能是:

        HTML

        <head>
            <meta name="_csrf" th:content="${_csrf.token}"/>
            <meta name="_csrf_header" th:content="${_csrf.headerName}"/>
        </head>
        

        JS

        function postExample() {
            let token = $("meta[name='_csrf']").attr("content");
            let header = $("meta[name='_csrf_header']").attr("content");
        
            let data = {username: "", password: "", firstname: "", lastname: ""};
        
            // Object key string interpolation by {[header]:token} works with ES6
            fetch(window.location+"/addnote", {
                method:"POST",
                headers: {
                    [header]: token,
                    "charset": "UTF-8",
                    "Content-Type": "application/json"
                },
                body: JSON.stringify(data)
            }).then(res => console.log(res)).catch(err => console.log(err))
        }
        

        【讨论】:

        • 能否请您提及控制器中的最后一部分如何检索数据
        【解决方案5】:

        以公认的答案为基础

        许多 HTTP 客户端库(例如 Axios)为 POST 请求隐式设置 Content-Type: JSON 标头。就我而言,我忘记允许该标头仅导致 POSTS 失败。

        @Bean
        CorsConfigurationSource corsConfigurationSource() {
            ...
            configuration.addAllowedHeader("Content-Type"); // <- ALLOW THIS HEADER 
            ...
        }
        

        【讨论】:

          【解决方案6】:

          你必须禁用 csrf 保护,因为它在 spring security 中默认启用:在这里你可以看到允许 cors 起源的代码。

          import org.springframework.context.annotation.Bean;
          import org.springframework.security.config.annotation.web.builders.HttpSecurity;
          import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
          import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
          import org.springframework.web.cors.CorsConfiguration;
          import org.springframework.web.cors.CorsConfigurationSource;
          import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
          
          @EnableWebSecurity
          public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
          
              @Override
              protected void configure(HttpSecurity http) throws Exception{
                  http.cors().and().csrf().disable();
              }
          
              @Bean
              CorsConfigurationSource corsConfigurationSource() {
                  CorsConfiguration configuration = new CorsConfiguration();
                  configuration.setAllowedOrigins(Arrays.asList("*"));
                  configuration.setAllowedMethods(Arrays.asList("*"));
                  configuration.setAllowedHeaders(Arrays.asList("*"));
                  configuration.setAllowCredentials(true);
                  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                  source.registerCorsConfiguration("/**", configuration);
                  return source;
              }
          
          }
          

          【讨论】:

          • 禁用 csrf 使我的 POST 请求成功!真是一种解脱。
          • 谢谢我的朋友!你节省了我的时间!
          • 为什么禁用 csrf 允许的 post 方法?
          • @Ezzat Eissa - 禁用csrf 确实有效。但这也使我们的 API 易受攻击,不是吗?如果是这样,如何确保从服务器端和客户端都配置了 csrf 令牌?
          • 这个答案应该带有一些警告。启用 csrf 有一些很好的理由。要启用 csrf:docs.spring.io/spring-security/site/docs/3.2.x/reference/…
          【解决方案7】:

          可能的原因:

          1. 邮递员完成的请求与移动设备完成的请求不同(uri、方法、标头)
          2. 令牌无效
          3. CORS(阅读有关它的内容,谷歌充满了文章)将 @CrossOrigin 注释添加到您的控制器。
          4. 移动应用在执行 POST 之前执行 OPTION 请求,而您阻止了 OPTION 请求。如果邮递员也阻止了 OPTION 请求,请添加属性 spring.mvc.dispatch-options-request=true。此外,如果您使用的是 Spring Security,您还必须明确允许 OPTION 请求。

          【讨论】:

          • 你能告诉我如何添加选项请求吗?@desoss
          • 我已经更新了第 4 点...让我知道 spring.mvc.dispatch-options-request=true 是否有效。
          • 是的,我正在尝试。我会告诉你是否有效
          • 是的,你是对的 - 来自 Postman 的 POST 请求被认为是 CORS,但只是想知道为什么即使 CORS 被禁用,来自 Postman 的 GET 请求也会通过?
          猜你喜欢
          • 2022-01-10
          • 1970-01-01
          • 1970-01-01
          • 2019-08-29
          • 2021-07-28
          • 1970-01-01
          • 2018-09-03
          • 1970-01-01
          • 2021-07-15
          相关资源
          最近更新 更多