2017-09-20 24 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

如果你想知道是什麼問題 - 數據庫返回的密碼和空格在它的結尾...這就是爲什麼它永遠不能進行身份驗證,提供的密碼總是與存儲在數據庫中的「不同」...上帝該死的。