春季安全投掷"原因:凭证错误" UI中的错误,但在登录期间正确查找用户

时间:2017-12-15 05:33:09

标签: java spring spring-boot spring-security

我已经筋疲力尽了每一篇SO帖子和博客文章,我可以找到我试图弄清楚我做错了什么。所以,现在我要求你的帮助。我正在构建一个Spring Boot应用程序并利用Spring Security进行用户管理/身份验证。我认为我已经正确设置了一切,但在登录期间,Spring Security每次都会重定向到登录失败URL(/ login?error),抛出错误:

您的登录尝试失败,请重试。 原因:凭据错误

服务器日志中没有任何说明或有用的信息。作为调试的一部分,我添加了一堆记录确认:

  1. 在数据库中找到用户(通过电子邮件,usernameParameter设置为在config中发送电子邮件
  2. Spring Security' userDetails.Usernew构造函数创建了正确的用户(我已记录用户的详细信息)
  3. 我是框架的新手,所以我可能会忽略某些东西,这是我非常感谢你的帮助。我已经在下方添加了我的安全配置和用户服务(我已经清除了日志以便为您的阅读进行清理) - 让我知道是否有任何其他内容会有所帮助。提前谢谢!

    SecurityConfiguration.java

    public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
    
    @Resource(name = "userService")
    private UserDetailsService userDetailsService;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/test").hasRole("USER")
                .antMatchers("/**").permitAll()
                .and().formLogin().usernameParameter("email").defaultSuccessUrl("/register_success");
        http.authorizeRequests()
                .antMatchers("/resources/**").permitAll();
        super.configure(http);
    }
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder authenticationManagerBuilder)
                                throws Exception {
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }
    
    // Define this bean so autowired can find and use it (fixes complaining error)
    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
    }
    

    UserService.java

    @Service("userService")
    public class UserService implements UserDetailsService {
    
    private static final String LOG_TAG = UserService.class.getSimpleName();
    private Logger logger = LoggerFactory.getLogger(LOG_TAG);
    
    private UserRepository userRepository;
    
    @Autowired
    SessionFactory sessionFactory;
    
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // Must provide email address as username argument
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByEmail(username);
        if (user == null) {
            throw new UsernameNotFoundException("There is no user with this email address.");
        }
        org.springframework.security.core.userdetails.User springUser = new org.springframework.security.core.userdetails.User(
                user.getEmail(), user.getPassword(), getAuthority());
        return springUser;
    }
    
    public User findByEmail(String email) {
        return userRepository.findByEmail(email);
    }
    
    public User findByConfirmationToken(String confirmationToken) {
        return userRepository.findByConfirmationToken(confirmationToken);
    }
    
    @Transactional
    public List<User> findAll() {
        Criteria criteria = sessionFactory.openSession().createCriteria(User.class);
        return (List<User>) criteria.list();
    }
    
    public void saveUser(User user) {
        userRepository.save(user);
    }
    
    //TODO: Figure out how to use this properly
    public List getAuthority() {
        return Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
    }
    }
    

1 个答案:

答案 0 :(得分:0)

添加新用户时,您需要使用PasswordEncoder加密密码。

像这样:

@Autowired
private BCryptPasswordEncoder passwordEncoder;
public void saveUser(User user) {
    user.setPassword(passwordEncoder.encode(user.getPassword()));
    userRepository.save(user);
}