我正在开发一个 Spring Boot 应用程序。我创建了一个PasswordEncoder类型的bean,但是当我运行代码时,它显示了以下错误
描述:
构造函数的参数1 com.example.FintechBackend.service.UserService 需要一个 bean 类型 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' 找不到。
行动:
考虑定义一个类型的bean 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' 中 您的配置。
虽然我已经在配置文件中声明了 bean,但仍然收到此错误。我很困惑如何解决它
以下是我的课程
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) {
try {
return http
.authorizeHttpRequests(authCustomizer -> authCustomizer
.requestMatchers(HttpMethod.POST,
"/api/users/register", "/api/users/login").permitAll()
.requestMatchers(HttpMethod.GET, "/api/users/{id}").hasRole("USER")
.requestMatchers(HttpMethod.PUT, "/api/users/{id}").hasRole("USER")
.requestMatchers(HttpMethod.DELETE, "/api/users/{id}").hasRole("USER")
.requestMatchers(HttpMethod.POST, "/api/transactions").hasRole("USER")
.requestMatchers(HttpMethod.GET, "/api/transactions/{id}").hasRole("USER")
.requestMatchers(HttpMethod.PUT, "/api/transactions/{id}").hasRole("USER")
.requestMatchers(HttpMethod.DELETE, "/api/transactions/{id}").hasRole("USER")
)
.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
配置类中创建的BCryptPasswordEncoder用于Userservice中,其代码如下
import com.example.FintechBackendDeveloperAssignment.DTO.UserRegistrationDTO;
import com.example.FintechBackendDeveloperAssignment.model.User;
import com.example.FintechBackendDeveloperAssignment.repository.UserRepository;
import org.slf4j.Logger;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
private final BCryptPasswordEncoder passwordEncoder;
private final Logger logger;
public UserService(UserRepository userRepository, BCryptPasswordEncoder passwordEncoder, Logger logger) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.logger = logger;
}
public User registerUser(UserRegistrationDTO registrationDTO) {
User existingUser = userRepository.findByEmail(registrationDTO.getEmail());
if (existingUser != null) {
throw new RuntimeException("Email already exists");
}
User user = new User();
user.setName(registrationDTO.getName());
user.setEmail(registrationDTO.getEmail());
user.setRole("USER");
user.setPassword(passwordEncoder.encode(registrationDTO.getPassword()));
userRepository.save(user);
logger.info("User registered: " + user.getEmail());
return user;
}
public User loginUser(String email, String password) {
User user = userRepository.findByEmail(email);
if (user == null || !passwordEncoder.matches(password, user.getPassword())) {
throw new RuntimeException("Invalid email or password");
}
logger.info("User logged in: " + user.getEmail());
return user;
}
}
我们正在控制器中创建此用户服务的对象,这是抛出错误的地方
import com.example.FintechBackendDeveloperAssignment.DTO.UserRegistrationDTO;
import com.example.FintechBackendDeveloperAssignment.model.Transaction;
import com.example.FintechBackendDeveloperAssignment.model.User;
import com.example.FintechBackendDeveloperAssignment.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@Tag(name = "post", description = "Post methods of user APIs")
@Operation(summary = "Register User",
description = "This APi is use to register new user in system")
@ApiResponses({
@ApiResponse(responseCode = "200", content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = User.class)) }),
@ApiResponse(responseCode = "404", description = "User not created",
content = @Content) })
@PostMapping("/register")
public ResponseEntity<?> registerUser(@Valid @RequestBody UserRegistrationDTO registrationDTO, BindingResult result) {
if (result.hasErrors()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Validation errors");
}
try {
User user = userService.registerUser(registrationDTO);
return ResponseEntity.status(HttpStatus.CREATED).body(user);
} catch (RuntimeException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
@Operation(summary = "Login User",
description = "This API is use to Login user in system")
@ApiResponses({
@ApiResponse(responseCode = "200", content = { @Content(mediaType = "application/json",
schema = @Schema(implementation = User.class)) }),
@ApiResponse(responseCode = "404", description = "User not LoggedIn",
content = @Content) })
@Tag(name = "post", description = "Post methods of user APIs")
@PostMapping("/login")
public ResponseEntity<?> loginUser(@RequestParam String email, @RequestParam String password) {
try {
User user = userService.loginUser(email, password);
return ResponseEntity.ok(user);
} catch (RuntimeException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(e.getMessage());
}
}
}
尝试更改服务构造函数中密码编码器的类型以匹配您正在创建的 bean 类型:
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, Logger logger)
问题是您正在创建的 bean 类型为
PasswordEncoder
并且 spring 正在寻找更具体类型 BCryptPasswordEncoder
的自动装配候选者。