Spring Boot:使用Spring Boot时只允许Postman“GET”请求,不允许“POST”、“PUT”或“DELETE”;他们会产生“401 Unauthorized”错误

问题描述 投票:0回答:1

我是

Spring Boot
的新手,现在,我正在根据 本教程 构建应用程序。我的代码如下所示。


代码片段

pom.xml
文件:

<?xml version="1.0"
      encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.pokemonreview</groupId>
    <artifactId>api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>api</name>
    <description>Pokemon Review API Course 2022</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>3.0.6</version>
        </dependency>
        <dependency>
            <groupId>com.rungroop</groupId>
            <artifactId>web</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.properties
文件(简单密码不是秘密,仅用于测试目的):

spring.datasource.url=jdbc:postgresql://localhost:5432/pokemonApiCourse
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=update
spring.security.user.name=test
spring.security.user.password=test
spring.jpa.show-sql=true

型号:

package com.pokemonreview.api.models;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class PokemonEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String type;
}

控制器:

package com.pokemonreview.api.controllers;

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.pokemonreview.api.models.PokemonEntity;

@RestController
@RequestMapping("/api/")
public class PokemonController {
    @GetMapping("pokemon")
    public ResponseEntity<List<PokemonEntity>> getPokemons() {
        List<PokemonEntity> pokemonEntities = new ArrayList<PokemonEntity>();
        pokemonEntities.add(new PokemonEntity(1L, "Squirtle", "Water"));
        pokemonEntities.add(new PokemonEntity(2L, "Pikachu", "Electric"));
        pokemonEntities.add(new PokemonEntity(3L, "Charmander", "Fire"));
        return ResponseEntity.ok(pokemonEntities);
    }
    
    @GetMapping("pokemon/{id}")
    public PokemonEntity pokemonDetail(@PathVariable Long id) {
        return new PokemonEntity(id, "Squirtle", "Water");
    }
    
    @PostMapping("pokemon/create")
    @ResponseStatus(HttpStatus.CREATED)
    public ResponseEntity<PokemonEntity> createPokemon(@RequestBody PokemonEntity pokemonEntity) {
        System.out.println(pokemonEntity.getName());
        System.out.println(pokemonEntity.getType());
        return new ResponseEntity<PokemonEntity>(pokemonEntity, HttpStatus.CREATED);
    }
    
    @PutMapping("pokemon/{id}/update")
    public ResponseEntity<PokemonEntity> updatePokemon(@RequestBody PokemonEntity pokemonEntity,
                                                       @PathVariable("id") Long id) {
        System.out.println(pokemonEntity.getName());
        System.out.println(pokemonEntity.getType());
        return ResponseEntity.ok(pokemonEntity);
    }
    
    @DeleteMapping("pokemon/{id}/delete")
    public ResponseEntity<String> deletePokemon(@PathVariable("id") Long id) {
        System.out.println(id);
        return ResponseEntity.ok("Pokemon deleted successfully");
    }
}

我所做的修改

请注意……

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>3.0.6</version>
</dependency>

… 是我添加到

pom.xml
文件中的,但它确实 not 是否存在有所不同。 总是需要身份验证——不管是否添加
Spring Security
依赖项! (这是为什么?在教程中,需要no授权!)——如果我不添加这两行……

spring.security.user.name=test
spring.security.user.password=test

…到

application.properties
文件,每次启动
user
应用程序时都会生成用户
Spring Boot
的密码。

此外,我的

id
变量不是
int
,如教程中所示,而是
Long

此外,请注意本教程中使用了

javax.persistence
包。唯一向我建议的包是
jakarta.persistence
包。


Postman
问题:只允许
GET
请求

我正在使用

Postman
来测试
GET
POST
PUT
DELETE
请求,但只有
GET
请求有效。 每次,我的
Authorization
选项卡中的选项设置如下:

  • Type:
    Basic Auth
    • Username:
      test
    • Password:
      test

工作
GET
请求

GET
上的第一个
http://localhost:8080/api/pokemon
请求产生以下结果:

[
    {
        "id": 1,
        "name": "Squirtle",
        "type": "Water"
    },
    {
        "id": 2,
        "name": "Pikachu",
        "type": "Electric"
    },
    {
        "id": 3,
        "name": "Charmander",
        "type": "Fire"
    }
]

GET
上第二次
http://localhost:8080/api/pokemon/5
请求的结果如下:

{
    "id": 5,
    "name": "Squirtle",
    "type": "Water"
}

失败
POST
PUT
DELETE
请求

POST
请求是在
http://localhost:8080/api/pokemon/create
上进行的,在
Body
选项卡中,选择了
raw
JSON
并插入以下内容:

{
    "name": "Pidgey",
    "type": "Earth"
}

如果我现在点击

Send
,什么都没有返回,状态
401 Unauthorized
显示。

PUT
http://localhost:8080/api/pokemon/5/update
)和
DELETE
http://localhost:8080/api/pokemon/5/delete
)请求产生相同的结果。

怎么了?在教程中,一切正常,我已经尝试根据我在互联网上找到的解决方案以多种方式调整

pom.xml
application.properties
文件,但所有这些都没有解决我的问题。

java spring-boot spring-security postman authorization
1个回答
0
投票

我终于找到问题所在了。

Spring Security
没有正确配置。当我添加以下包和类时,一切都开始正常工作:

package com.pokemonreview.api.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {   
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {        
        httpSecurity.csrf()
                    .disable()
                    .authorizeHttpRequests()
                    .requestMatchers("/api/pokemon/**")
                    .permitAll();
        return httpSecurity.build();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.