Spring Boot 401未授权,即使有正确的用户名和密码

tzcvj98z  于 2023-02-19  发布在  Spring
关注(0)|答案(1)|浏览(163)

我正在创建一个用户API,并尝试通过 Boot 安全性实现一个身份验证方法。
即使使用正确的密码和默认的Spring Security用户user,我的Postman仍然给我一个授权错误,我看不出问题出在这段代码中。
安全配置:

package com.api.business_products_management.config;

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 http) throws Exception {
        http
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .httpBasic();
        return http.build();
    }
}

控制器:

package com.api.business_products_management.controllers;

import com.api.business_products_management.dtos.UserDto;
import com.api.business_products_management.models.UserModel;
import com.api.business_products_management.services.UserService;
import jakarta.validation.Valid;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping("/user")
public class UserController {

    private BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping
    public ResponseEntity<Object> saveUser(@RequestBody @Valid UserDto userDto) {
        var userModel = new UserModel();
        BeanUtils.copyProperties(userDto, userModel);
        userModel.setPassword(passwordEncoder().encode(userModel.getPassword()));
        return ResponseEntity.status(HttpStatus.CREATED).body(userService.save(userModel));
    }
}

控制台:

2023-02-17T18:24:13.152-03:00  INFO 8418 --- [nio-8099-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-02-17T18:24:13.152-03:00  INFO 8418 --- [nio-8099-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-02-17T18:24:13.154-03:00  INFO 8418 --- [nio-8099-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
fnx2tebb

fnx2tebb1#

在没有看到您的Postman请求的情况下,我最初的猜测是缺少CSRF(来自您的Postman请求)导致了401。您可以在此处阅读有关Spring中CSRF的更多信息:https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html
根据该文件:
从Spring Security 4.0开始,默认情况下启用CSRF保护
您可以通过临时禁用CSRF来测试这一理论,如下面的示例配置所示:
https://docs.spring.io/spring-security/site/docs/5.0.x/reference/html/csrf.html#csrf-configure
即:

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .anyRequest().authenticated()
                .and()
            .httpBasic();
        return http.build();
    }
}

我强烈建议您阅读文档的其余部分,以熟悉CSRF的保护措施,以及在生产环境中禁用CSRF之前,将其关闭(或选择性地禁用某些路径)是否是可接受的风险。

相关问题