spring 即使UserDetailsManager.loadUserByUsername返回非null,AuthenticationManager.authenticate也会失败

yhqotfr8  于 2023-04-04  发布在  Spring
关注(0)|答案(1)|浏览(242)

我想在我的SpringBoot应用程序中使用UserDetailsManager创建一个用户,并使用AuthenticationManager对用户进行身份验证。配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

}

    @Bean
    public UserDetailsManager userDetailsManager() {
        UserDetails user =
                User.withDefaultPasswordEncoder()
                        .username("user")
                        .password("password")
                        .roles("USER")
                        .build();

        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }

控制器

@RestController
public class AuthenticationController {

    private final UserDetailsManager userDetailsManager;
    private final AuthenticationManager authenticationManager;
    private final List<GrantedAuthority> grantedAuthorityList = List.of(new SimpleGrantedAuthority("USER"));

    @PostMapping("/login")
    ResponseEntity<AuthenticationResponse> login(@RequestBody AuthenticationRequest form) {

        try {
            var user = userDetailsManager.loadUserByUsername(form.username()); // Not null, valid user
            authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(form.username(), form.password(), this.grantedAuthorityList)
            ); // throws AuthenticationException
             ...

        } catch (AuthenticationException e) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
    }
}

之前使用此创建了用户

userDetailsManager.createUser(new User(form.username(), form.password(), this.grantedAuthorityList));

任何帮助都很感激

qxsslcnc

qxsslcnc1#

即使UserDetailsManager.loadUserByUsername()返回非空值,AuthenticationManager.authenticate()也会失败的原因可能是由于密码编码不正确或身份验证提供程序配置不正确。
WebSecurityConfig类中使用的User.withDefaultPasswordEncoder()方法使用了一个已弃用且不安全的密码编码器,不建议在生产环境中使用。建议使用更安全的密码编码器,如BCryptPasswordEncoder,它在Spring Security中可用。
您可以使用User.builder()和BCryptPasswordEncoder替换User.withDefaultPasswordEncoder()方法,如下所示:

public UserDetailsManager userDetailsManager() {
    PasswordEncoder encoder = new BCryptPasswordEncoder();
    UserDetails user = User.builder()
            .username("user")
            .password(encoder.encode("password"))
            .roles("USER")
            .build();

    return new InMemoryUserDetailsManager(user);
}

此外,您需要确保正确配置身份验证提供程序以使用UserDetailsManager。您可以通过将以下配置添加到WebSecurityConfig类来完成此操作:

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, UserDetailsManager userDetailsManager) throws Exception {
    auth.userDetailsService(userDetailsManager);
}

通过这些更改,AuthenticationManager.authenticate()现在应该能够成功地对用户进行身份验证。

相关问题