我创建了一个PasswordEncoder类型的bean,但我的springboot应用程序仍然显示我没有任何这样的bean

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

我正在开发一个 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());
        }
    }
}

以下是我的代码结构。

java spring spring-boot javabeans
1个回答
0
投票

尝试更改服务构造函数中密码编码器的类型以匹配您正在创建的 bean 类型:

public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, Logger logger)

问题是您正在创建的 bean 类型为

PasswordEncoder
并且 spring 正在寻找更具体类型
BCryptPasswordEncoder
的自动装配候选者。

© www.soinside.com 2019 - 2024. All rights reserved.