2017-09-20 18 views
0

我对Spring Security和加密密码有问题MsSQL。在我的REST应用程序中,我使用了Spring 4,HibernateSpring Data JPA。我试图实现与Bcrypt密码加密,但我只是想用正确的凭据登录时获得Spring Security不承认自己的加密

WARN 4780 --- [io-8080-exec-61] o.s.s.c.bcrypt.BCryptPasswordEncoder 
:Encoded password does not look like BCrypt 

。然后访问显然被拒绝。

我试过还是什么我知道:在MS SQL

  1. 密码被正确地存储,作为Bcrypt加密字符串
  2. 将在DB的密码足够长(64个字符)
  3. 添加到AuthenticationManagerBuilder auth.jdbcAuthentication().dataSource(dataSource)没有改变任何东西。
  4. 当向DB询问密码时,它会返回存储的内容 - Brypt编码的密码。

整个事情有点奇怪,因为我使用相同的PasswordEncoder实例来编码一切。然后它不认可它自己的加密。我有什么:

配置:

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
     @Autowired 
     private RESTAuthenticationEntryPoint authenticationEntryPoint; 

     @Autowired 
     private RESTAuthenticationFailureHandler authenticationFailureHandler; 

     @Autowired 
     private RESTAuthenticationSuccessHandler authenticationSuccessHandler; 

     @Autowired 
     private UserDetailsService userAuthService; 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
        .csrf().disable() 
        .authorizeRequests() 
         .antMatchers("/home", "/").permitAll() 
         .antMatchers("/login").permitAll() 
         .antMatchers("/addGame").hasRole("USER") 
        .and() 
        .exceptionHandling() 
         .authenticationEntryPoint(authenticationEntryPoint) 
        .and() 
        .formLogin() 
         .successHandler(authenticationSuccessHandler) 
         .failureHandler(authenticationFailureHandler); 

    } 

     @Override 
     protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
      auth.authenticationProvider(authenticationProvider()); 
     } 

     @Bean 
     public DaoAuthenticationProvider authenticationProvider() { 
      DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); 
      authProvider.setUserDetailsService(userAuthService); 
      authProvider.setPasswordEncoder(encoder()); 
      return authProvider; 
     } 

     @Bean 
     public PasswordEncoder encoder() { 
      return new BCryptPasswordEncoder(); 
     } 

} 

的UserDetailsS​​ervice:

@Service 
public class UserAuthService implements UserDetailsService{ 
    @Autowired 
    UserDatabaseService userDatabaseService; 

    @Override 
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     UserDto user = userDatabaseService.getUserByUsername(username); 
     if (user == null){ 
      throw new UsernameNotFoundException(username); 
     } else{ 
      return new MyUserPrincipal(user); 
     } 

    } 

} 

UserDatabaseService(与Spring数据来实现):

@Service 
public class UserDatabaseService { 

    @Autowired 
    UserDatabaseRepository userDatabaseRepository; 

    @Autowired 
    UserToUserDtoConverter userToUserDtoConverter; 

    @Autowired 
    UserDtoToUserEntityConverter userDtoToUserEntityConverter; 

    @Autowired 
    PasswordEncoder passwordEncoder; 

    public UserDto getUserByUsername(String username){ 
     return userToUserDtoConverter.convert(userDatabaseRepository.findByUsername(username)); 
    } 

    public boolean saveUser(UserDto user){ 
     user.setPassword(passwordEncoder.encode(user.getPassword())); 
     if (userDatabaseRepository.save(userDtoToUserEntityConverter.convert(user)) != null){ 
      return true; 
     } else{ 
      return false; 
     } 
    } 

} 

说实话,我真的不知道什么是错。我一直在关注这两个教程: http://www.baeldung.com/spring-security-authentication-with-a-database http://www.baeldung.com/spring-security-registration-password-encoding-bcrypt

所有帮助将非常感激。

编辑:转换器用于DTO类转化为实体(反之亦然)

@Service 
public class UserDtoToUserEntityConverter { 
    public UserEntity convert(UserDto user){ 
     return new UserEntity(user.getFirstName(), user.getLastName(), user.getUsername(), user.getPassword() , user.getEmail()); 
    } 

    public Collection<UserEntity> convertAll(Collection<UserDto> fElements){ 
     Collection<UserEntity> convertedElement = 
       fElements.stream() 
         .map(element -> convert(element)) 
         .collect(Collectors.toList()); 
     return convertedElement; 
    } 

} 

@Service 
public class UserToUserDtoConverter implements UserDtoConverter { 

    @Override 
    public UserDto convert(UserEntity from) { 
     return new BaseUserDto(from.getFirstName(), from.getLastName(), 
           from.getUsername(), from.getPassword(), 
           from.getEmail()); 
    } 

} 

MyUserPrincipal:

public class MyUserPrincipal implements UserDetails{ 
    private UserDto user; 

    public MyUserPrincipal(UserDto user) { 
     this.user = user; 
    } 

    @Override 
    public Collection<? extends GrantedAuthority> getAuthorities() { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 

    @Override 
    public String getPassword() { 
     return user.getPassword(); 
    } 

    @Override 
    public String getUsername() { 
     return user.getUsername(); 
    } 

    @Override 
    public boolean isAccountNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isAccountNonLocked() { 
     return true; 
    } 

    @Override 
    public boolean isCredentialsNonExpired() { 
     return true; 
    } 

    @Override 
    public boolean isEnabled() { 
     return true; 
    } 



} 
+0

@dur我编辑了原来的问题,如果你可以看看我会很感激。那些转换器不会做太多的事情。 – Stompy

+0

是的,我试过了 - 它返回正确编码的密码。然而,不仅编码有问题 - 没有它,我也无法登录。Spring Data是否讨厌Hibernate或其他?......? – Stompy

+0

MyUserPrincipal是实现Spring Security的“UserDetails”接口的类。我已经为问题添加了代码,它也没有做太多... – Stompy

回答

0

如果你想知道是什么问题 - 数据库返回的密码和空格在它的结尾...这就是为什么它永远不能进行身份验证,提供的密码总是与存储在数据库中的“不同”...上帝该死的。