Put 请求在 Spring Web 中给出错误 401/403

Put request gives Errors 401/403 in Spring Web

我有一个简单的 PUT 请求,它在本地 h2 数据库中连续保存一本书。使用邮递员,当我首先发送请求时,在另一个之前,它 returns 我一个 401 错误 - 没有数据。截图:1: . But if I execute the request after another (a GET Request, which executes successfully), the PUT request return a 403 forbidden error。我使用本地 h2 内存数据库并用此代码填充它(我还设置了一个模式 - 否则它不会识别 table 名称):

DROP TABLE IF EXISTS BOOKS;
CREATE TABLE BOOKS(
isbn LONG  AUTO_INCREMENT PRIMARY KEY,
count_books INT NOT NULL,
author VARCHAR(30) NOT NULL,
name VARCHAR(30) NOT NULL UNIQUE,
description VARCHAR(250)
);

INSERT INTO BOOKS (count_books, author, name, description) VALUES
  (2,'Иван Вазов', 'Под Игото', 'В малко градче пристига странник и им показва значението на свободата'),
  (4,'Тютюн', 'Димитър Димов', 'История за човешки характери, поквара и любов на фона на ВСВ.'),
  (6,'Клетниците', 'Виктор Юго', 'Разтърсваща история за човешкия падеж и неговото възстановяване.');

至于其余 API,我使用 Spring Boot,以及 Web、H2、PostGre 和 OAuth 2.0(将来)。这是我的服务 class(充当 DAO):

package Library.demo.dao;

import Library.demo.entities.Books;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.LinkedList;

@Service
public class BooksDAOImpl {
    @Autowired
    BookRepository bookRepository;

    public LinkedList<Books> get_all_books() {
        LinkedList<Books> books = new LinkedList<>();
            for(Books book : bookRepository.findAll()) {
                books.add(book);
            }
        System.out.println(bookRepository.count());
        return books;
    }
    public void addBook_admin(int count, String name, String author, String description){
        Books book = new Books(count,name, author,description);
        bookRepository.save(book);
        System.out.println(bookRepository.count());
    }

}

这是我的 REST 控制器 class,用于将书籍添加到数据库:

package Library.demo.command;

import Library.demo.dao.BooksDAOImpl;
import org.hibernate.NonUniqueObjectException;
import org.hibernate.exception.JDBCConnectionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

import java.util.InputMismatchException;

@RestController
public class Add_book_admin_command {
    @Autowired
    BooksDAOImpl bookDAO;

    @PutMapping("/books/add")
    public void execute(@RequestParam int count_books, @RequestParam String author, @RequestParam String name, @RequestParam String description) {
        try {
            bookDAO.addBook_admin(count_books, author, name, description);
        }catch (InputMismatchException ime){
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Wrong type of information");
        }catch (JDBCConnectionException jdbcConnectionException){
            throw new ResponseStatusException(HttpStatus.BAD_GATEWAY, "Error connecting to database");
        }catch (NonUniqueObjectException objectException){
            throw new ResponseStatusException(HttpStatus.NOT_ACCEPTABLE, "Book already exists");
        }
    }
}

这是我获取所有书籍的控制器:

package Library.demo.command;

import Library.demo.dao.BooksDAOImpl;
import Library.demo.entities.Books;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.LinkedList;


@RestController
public class List_all_books_admin_command {
    @Autowired
    BooksDAOImpl bookDAO;
    @GetMapping("/books/all")
    public LinkedList<Books> execute() {
        return bookDAO.get_all_books();
    }


}

还有我的 application.settings 文件:

spring.datasource.url=jdbc:h2:mem:test;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.hibernate.ddl-auto=none
security.basic.enable= false
security.ignored=/**

我的实体 class 是图书:

package Library.demo.entities;

import javax.persistence.*;

@Entity(name = "BOOKS")
public class Books {

    @Id
    @GeneratedValue
    private long isbn;

    private int count_books;

    private String author;

    private String name;

    private String description;

    public Books( int count_books, String author, String name, String description) {
        this.count_books = count_books;
        this.author = author;
        this.name = name;
        this.description = description;
    }

    public Books() {
    }


    public long getIsbn() {
        return isbn;
    }

    public void setIsbn(int isbn) {
        this.isbn = isbn;
    }

    public int getCount() {
        return count_books;
    }

    public void setCount(int count) {
        this.count_books = count;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

程序构建得很好,即使 PUT 请求失败,控制台输出也没有异常。我是 Spring 框架的新手,所以任何帮助将不胜感激:)

答案 - 通过 WebSecurityConfig class 关闭 csrf。 代码片段:

@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(Collections.singletonList("*"));
        configuration.setAllowedMethods(Collections.singletonList("*"));
        configuration.setAllowedHeaders(Collections.singletonList("*"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

这应该可以解决问题