【问题标题】:Put request gives Errors 401/403 in Spring Web放置请求在 Spring Web 中给出错误 401/403
【发布时间】:2021-09-21 13:49:20
【问题描述】:

我有一个简单的 PUT 请求,它将一本书连续保存在本地 h2 数据库中。使用邮递员,当我先发送请求时,它会返回一个 401 错误 - 没有数据。截图:1。但是如果我一个接一个地执行请求(一个GET请求,执行成功),PUT请求返回一个403禁止错误。我使用本地 h2 内存数据库并使用此代码填充它(我还设置了一个模式 - 否则它将无法识别表名):

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,'Клетниците', 'Виктор Юго', 'Разтърсваща история за човешкия падеж и неговото възстановяване.');

至于 Rest API,我使用 Spring Boot,以及 Web、H2、PostGre 和 OAuth 2.0(将来)。这是我的服务类(充当 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 控制器类:

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=/**

我的实体类是 Books :

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 框架还很陌生,所以任何帮助都将不胜感激:)

【问题讨论】:

  • 尝试将security.enable_csrf: false 添加到您的属性文件中
  • 是安全配置问题。你的配置是什么?
  • 抱歉让您久等了 - 我关闭了 csrf 并且它起作用了

标签: java spring-boot hibernate spring-mvc spring-data-jpa


【解决方案1】:

Answer - 通过 WebSecurityConfig 类关闭 csrf。 代码sn-p:

@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;
    }
}

这应该可以解决问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-08
    • 2018-12-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    相关资源
    最近更新 更多