2013-10-24 186 views
1

需要一些幫助或使用Spring的安全3.1.x的方向。春季安全密碼驗證

我在MySql數據庫中存儲加密密碼。哪個密碼被定義爲varchar(60)列。

第一次運行的Web應用程序,我用下面的代碼片段生成的密碼:

String p = "12345"; 
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
String encodedPassword = passwordEncoder.encode(p); 

我取了字符串encodedPassword並粘貼到數據庫列。我將代碼保存在我的身份驗證管理器(以下代碼片段)中,並將encodedPassword記錄到服務器日誌中。

<security:authentication-manager alias="authenticationManager"> 
    <security:authentication-provider user-service-ref="usersDAO"> 
     <security:password-encoder ref="encoder" /> 
    </security:authentication-provider> 
</security:authentication-manager> 

<bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" /> 

我的問題是身份驗證失敗,出現異常:當BCryptPasswordEncoder.matches()運行不良的憑據。存儲的密碼與表單輸入中生成的散列不匹配。使用了初始散列生成中使用的相同文本密碼。

每次我重新運行登錄輸入相同的文本時,記錄的encodedPassword是不同的。調試我可以看到實體從數據庫中正確返回的位置,所以我不認爲這是一個問題。這個問題在我看來,我沒有做/正確設置一些東西,以便每次輸入文本 密碼時生成相同的散列。編輯: 添加usersDAO。編號: 加入實現。

import org.springframework.dao.DataAccessException; 
import org.springframework.security.core.userdetails.UserDetails; 
import org.springframework.security.core.userdetails.UsernameNotFoundException; 
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 
import org.springframework.security.crypto.password.PasswordEncoder; 
import org.springframework.stereotype.Repository; 
import org.springframework.transaction.annotation.Transactional; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 


@Repository("usersDAO") 
public class UsersDAO_DB extends AbstractHibernateDao<Users> implements UsersDAO 
{ 
final Logger log = LoggerFactory.getLogger(this.getClass()); 

@Override 
public Users getByUsername(String username) 
{ 
    String p = "12345"; 
    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
    String encodedPassword = passwordEncoder.encode(p); 
    log.debug("HELLOZ ----> " + encodedPassword); 

    notNull(username, "username can't be null"); 
    return (Users) getSession() 
     .getNamedQuery("users.byUsername") 
     .setParameter("username", username) 
     .uniqueResult(); 
} 

@Override 
@Transactional 
public UserDetails loadUserByUsername(String username) throws  UsernameNotFoundException, DataAccessException { 
    notNull(username, "username can't be null"); 
    Users users = getByUsername(username); 
    if (users == null) { 
     throw new UsernameNotFoundException("No user with username " + username); 
    } 
    return users; 
} 


@Override 
public void create(Users t) 
{ 
    // TODO Auto-generated method stub 
} 

@Override 
public void update(Users t) 
{ 
    // TODO Auto-generated method stub 

} 

@Override 
public void delete(Users t) 
{ 
    // TODO Auto-generated method stub 

} 

}

任何想法?

回答

2

這是一個新手的錯誤,這裏有幾個不同的教程。

在bean我已經確定我的安全編碼爲: org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder

要生成我用下面的代碼測試神祕的密碼:

String p = "12345"; 
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 
String encodedPassword = passwordEncoder.encode(p); 
log.debug("HELLOZ ----> " + encodedPassword); 

這是混合org.springframework.security.crypto.password.PasswordEncoder和org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder。請參閱上面的代碼來定義passwordEncoder。

有一次,我把它改爲:

String p = "12345"; 
BCryptPasswordEncoder pe= new BCryptPasswordEncoder(); 
String encPassword =pe.encode(p); 
log.debug("HELLB ----> " + encPassword); 

複製輸出到我的數據庫,並重新測試,一切運行良好。

1

每次我重新運行輸入相同的文字,記錄的encodedPassword是不同的」登錄。

哪裏是從記錄來的?春季安全將無法登錄進入的密碼,如果你使用BCrypt它應該重新編碼不被他們從頭開始的任何地方。

這聲音,就可以重新編碼等提交的密碼你自己,可能在你的usersDAO未示出。

如果沒有,請發佈您正在討論的完整配置和日誌輸出。

+0

不,我沒有對輸入的純文本密碼做任何事情,但生成一個用於打印調試語句的散列。當我說登錄密碼時,這就是我正在談論的。 – Ron

+0

由於BCrypt每次使用不同的鹽,散列總是會有所不同,所以這並不意味着什麼。我仍然猜測你自己的DAO正在發生。您發佈的界面沒有任何代碼,除非您發佈實際的實現,否則很難說。 –

+0

對不起,我不知道你需要什麼。如果您需要更多,請讓我知道。我收集到鹽是造成無與倫比的密碼,但這是我能夠收集的。 – Ron