【问题标题】:403 forbidden when I try to post to my spring api?当我尝试发布到我的 spring api 时,403 被禁止?
【发布时间】:2019-02-26 04:53:57
【问题描述】:

使用邮递员,我可以通过以下方式获取用户列表:http://localhost:8080/users

但是当我向同一个地址发送 post 请求时,我收到 403 错误。

@RestController
public class UserResource {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users")
    public List<User> retrievaAllUsers() {
        return userRepository.findAll();
    }


        @PostMapping("/users")
        public ResponseEntity<Object> createUser(@RequestBody User user) {
            User savedUser = userRepository.save(user);

            URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                    .path("/{id}")
                    .buildAndExpand(savedUser.getId())
                    .toUri();

            return ResponseEntity.created(location).build();

        }


    }


@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)

public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    /*@Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(userDetailsService)
                .passwordEncoder(new BCryptPasswordEncoder());
    }*/


    /*@Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests()
                .antMatchers("/users/**").hasRole("ADMIN")
                .and().csrf().disable().headers().frameOptions().disable();
    }*/
}

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String password;
    @Enumerated(EnumType.STRING)
    private Role role;

    // TODO which cna be removed

    public User() {
        super();
    }

    public User(Long id, String name, String password, Role role) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.role = role;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}





    @Repository
    public interface UserRepository extends JpaRepository<User, Long> {


    }






INSERT INTO user VALUES (1, 'user1', 'pass1', 'ADMIN'); 
INSERT INTO user VALUES (2, 'user2', 'pass2', 'USER'); 
INSERT INTO user VALUES (3,'user3', 'pass3', 'ADMIN')

编辑

编辑 2

添加了删除,但它也给出了 403?

@DeleteMapping("/users/{id}")

public void deleteUser(@PathVariable long id) { userRepository.deleteById(id); }

编辑 4

@EnableWebSecurity
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)

    public class SecurityConfig extends WebSecurityConfigurerAdapter {


        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/users/**").permitAll();

        }
    }



@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }


}

【问题讨论】:

  • 邮递员有时会做一些棘手的事情来让自己工作。你有没有比较每个请求中的标头,看看是否有任何差异?
  • 是否有类似Access is denied 之类的堆栈跟踪?
  • @benjaminc 我没有看到任何东西,而且我已经禁用了授权,所以不知道为什么会有任何东西?
  • @ab11 因为使用了@EnableWebSecurity,请尝试禁用csrf支持.csrf().disable()
  • @drowny 你是对的,当我添加.and().csrf().disable();时它起作用了

标签: java spring spring-boot spring-security


【解决方案1】:

SecurityConfig 类中的这个配置帮我解决了:

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

【讨论】:

    【解决方案2】:

    当您使用带有 Spring Security 的 Spring Boot 时,如果您从 Postman 或其他工具访问您的 API(POST、PUT、DELETE),它们将无法访问,并且错误与授权有关,例如禁止 403。

    因此,在这种情况下,您必须禁用 csrf 功能才能从 Postman 运行和测试 API。

    @benjamin c 提供的答案是正确的。您必须添加具有此配置的类才能工作。

    确保在生产环境中添加代码时将其删除。 CSRF 保护是必须的,您必须将其保留在安全功能中。

    我只是通过提供完整的课程详细信息来扩展他的答案以获取更多详细信息。我的要求是只测试 Postman 的 API,所以我添加了这个类,并且能够测试 Postman 的 API。

    但在那之后我添加了 Spring Junit 类来测试我的功能并删除了这个类。

    @Configuration
    @EnableWebSecurity
    public class AppWebSecurityConfigurer extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {    
            http
                .csrf().disable()
                .authorizeRequests()
                    .anyRequest().permitAll();
            }
    }
    

    希望这对某人有所帮助。

    【讨论】:

      【解决方案3】:

      @EnableWebSecurity 启用 Spring Security,默认启用 csrf 支持,您必须禁用它以防止 403 错误。

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

      或在每个请求中发送csrf 令牌。

      注意:禁用csrf 会降低应用程序的安全性,最好的办法是发送csrf 令牌。

      【讨论】:

      • 谢谢,但我如何将 csrf 令牌发送到 api?我知道在html页面标签表单中我们使用th:action="@{url}",但是当我们使用api时,我们直接访问restcontroller方法。
      【解决方案4】:

      403 表示您没有授权。即使您注释掉了您的方法,您的代码仍将预先配置默认安全访问权限。

      您可以添加:

      http.authorizeRequests()
         .antMatchers("/users/**").permitAll();
      

      更新:禁用 csrf 的配置:

      http.csrf()
           .ignoringAntMatchers("/users/**")
           .and()
           .authorizeRequests()
              .antMatchers("/users/**").permitAll();
      

      【讨论】:

      • 谢谢,我更新了我的 SecruityConfig,但在删除和创建时得到相同的 403。请使用我的新 SecurityConfig 查看我的最新编辑。它可能与应用程序类有关吗?我也包括了它的来源
      • 还添加 http.csrf().disable();同样从您的屏幕截图中,您尝试发布用户列表,并且在您的方法中您只有一个用户。
      【解决方案5】:

      请像这样配置你的http;

      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
              //configureothers if u wants.
              .csrf().disable();
      }
      

      请阅读更多CSRF

      【讨论】:

        猜你喜欢
        • 2019-09-03
        • 2019-07-12
        • 2013-08-06
        • 1970-01-01
        • 1970-01-01
        • 2021-04-29
        • 2012-10-13
        • 2021-12-15
        • 2015-09-23
        相关资源
        最近更新 更多