Spring安全性:密码don';与存储的不匹配
我有一个密码哈希问题。我想使用salt和1024次迭代来应用sha-256,以使用SpringSecurity对我的用户进行身份验证。但不知何故,我在数据库中的密码与用户输入的密码不匹配 这是我的密码: 安全上下文.xmlSpring安全性:密码don';与存储的不匹配,spring,security,Spring,Security,我有一个密码哈希问题。我想使用salt和1024次迭代来应用sha-256,以使用SpringSecurity对我的用户进行身份验证。但不知何故,我在数据库中的密码与用户输入的密码不匹配 这是我的密码: 安全上下文.xml <beans:bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" > <b
<beans:bean
id="passwordEncoder"
class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" >
<beans:constructor-arg value="256" />
<beans:property
name="iterations"
value="1024" />
</beans:bean>
<beans:bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource">
<beans:property name="userPropertyToUse" value="id"/>
</beans:bean>
<authentication-manager>
<authentication-provider user-service-ref="userLoginDetails" >
<password-encoder ref="passwordEncoder" >
<salt-source ref="saltSource"/>
</password-encoder>
</authentication-provider>
</authentication-manager>
用户登录详细信息
@Transactional(readOnly = true)
public class UserLoginDetails implements UserDetailsService {
private EregDaoFactory daoFactory;
@Autowired
public void setDaoFactory(EregDaoFactory daoFactory) {
this.daoFactory = daoFactory;
}
/**
* Retrieves a user record containing the user's credentials and access.
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,
DataAccessException {
Logger logger = Logger.getLogger(getClass());
logger.setLevel(Level.ALL);
int userId = Integer.parseInt(username);
UzytkownikDao dao = daoFactory.getUzytkownikDao();
LoggedUser user = null;
Uzytkownik dbUser = null;
try {
dbUser = (Uzytkownik) dao.findById(Integer.parseInt(username));
List<SimpleGrantedAuthority> grants = new ArrayList<SimpleGrantedAuthority>();
Collection<Object> userNames = new ArrayList<Object>();
if (dbUser.getRola() == 'U') {
grants.add(new SimpleGrantedAuthority("ROLE_STUDENT"));
userNames = daoFactory.getUczenDao().getNameAndLastName(userId);
} else if (dbUser.getRola() == 'N') {
grants.add(new SimpleGrantedAuthority("ROLE_TEACHER"));
userNames = daoFactory.getNauczycielDao().getNameAndLastName(userId);
} else if (dbUser.getRola() == 'O') {
grants.add(new SimpleGrantedAuthority("ROLE_PARENT"));
userNames = daoFactory.getOpiekunDao().getNameAndLastName(userId);
}
grants.add(new SimpleGrantedAuthority("ROLE_USER"));
Object[] names = userNames.toArray();
user =
new LoggedUser(username, dbUser.getHaslo(), true, true, true, true, grants,
(String) names[0], (String) names[1], dbUser.getRola());
} catch (Exception e) {
logger.error(e.getLocalizedMessage());
throw new UsernameNotFoundException("Error in retrieving user");
}
return user;
}
private void encryptPasswords() throws Exception {
OneWayEncryptor encryptor = OneWayEncryptor.getInstance();
appContext =
new FileSystemXmlApplicationContext(
"C:/EclipseWorkSpace/myereg/WebContent/WEB-INF/applicationContext.xml");
ds = (DataSource) appContext.getBean("dataSource");
JdbcTemplate jdbc = new JdbcTemplate(ds);
BigDecimal userId = null;
String password = "";
String encrypted = "";
Map<?, ?> row = new HashMap<Object, Object>();
for (Iterator<?> it = jdbc.queryForList("SELECT id, haslo FROM UZYTKOWNIK").iterator(); it.hasNext();) {
row = (Map<?, ?>) it.next();
userId = (BigDecimal) row.get("ID");
password = (String) row.get("HASLO");
encrypted = encryptor.encrypt(password, userId.toString());
System.out.println(userId.toString());
jdbc.execute("UPDATE UZYTKOWNIK SET haslo = '" + encrypted + "' WHERE id = " + userId);
}
}
public static void main(String[] args) {
EncryptAllUserPasswords encrypt = new EncryptAllUserPasswords();
try {
encrypt.encryptPasswords();
} catch (Exception e) {
e.printStackTrace();
}
}
@Transactional(readOnly=true)
公共类UserLoginDetails实现UserDetails服务{
私营电子设备厂;
@自动连线
公共无效setDaoFactory(EregDaoFactory){
this.daoFactory=daoFactory;
}
/**
*检索包含用户凭据和访问权限的用户记录。
*/
@凌驾
public UserDetails loadUserByUsername(字符串用户名)引发UsernameNotFoundException,
DataAccessException{
Logger=Logger.getLogger(getClass());
logger.setLevel(Level.ALL);
int userId=Integer.parseInt(用户名);
UzytkownikDao=daoFactory.getUzytkownikDao();
LoggedUser user=null;
Uzytkownik dbUser=null;
试一试{
dbUser=(Uzytkownik)dao.findById(Integer.parseInt(username));
List grants=new ArrayList();
集合用户名=new ArrayList();
if(dbUser.getRola()=='U'){
添加(新的简化授权(“角色学生”);
userNames=daoFactory.getUczenDao().getNameAndLastName(userId);
}else if(dbUser.getRola()=“N”){
添加(新的SimpleGrantedAuthority(“角色教师”);
userNames=daoFactory.getNauczycielDao().getNameAndLastName(userId);
}else if(dbUser.getRola()=“O”){
添加(新的SimpleGrantedAuthority(“角色家长”);
userNames=daoFactory.getOpiekunDao().getNameAndLastName(userId);
}
添加(新的SimpleGrantedAuthority(“角色用户”);
对象[]名称=用户名。toArray();
使用者=
新的LoggedUser(用户名,dbUser.getHaslo(),true,true,true,grants,
(字符串)名称[0],(字符串)名称[1],dbUser.getRola();
}捕获(例外e){
logger.error(例如getLocalizedMessage());
抛出新的UsernameNotFoundException(“检索用户时出错”);
}
返回用户;
}
}
LoggedUser
package ereg.security.userdetails;
public class LoggedUser extends User {
private static final long serialVersionUID = 1L;
private final String id;
private final String imie;
private final String nazwisko;
private final char rola;
private Date lastSuccessfulLogin;
private String lastKnowIpAddress;
public LoggedUser(String username, String password, boolean enabled, boolean accountNonExpired,
boolean credentialsNonExpired, boolean accountNonLocked,
Collection<? extends GrantedAuthority> authorities, String name, String lastName, char rola) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
authorities);
this.imie = name;
this.nazwisko = lastName;
this.rola = rola;
this.id = username;
}
public String getId() {
return id;
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public char getRola() {
return rola;
}
public Date getLastSuccessfulLogin() {
return lastSuccessfulLogin;
}
public String getFormattedDate() {
if (lastSuccessfulLogin != null) {
return new SimpleDateFormat("dd/MM/yyyy, HH:mm:ss").format(lastSuccessfulLogin);
} else
return null;
}
public String getLastKnowIpAddress() {
return lastKnowIpAddress;
}
public void setLastSuccessfulLogin(Date lastSuccessfulLogin) {
this.lastSuccessfulLogin = lastSuccessfulLogin;
}
public void setLastKnowIpAddress(String lastKnowIpAddress) {
this.lastKnowIpAddress = lastKnowIpAddress;
}
public final class OneWayEncryptor {
private static final OneWayEncryptor INSTANCE = new OneWayEncryptor();
private static final int ITERATIONS = 1024;
private static final String ALGORITHM = "SHA-256";
private OneWayEncryptor() {
}
public static OneWayEncryptor getInstance() {
return INSTANCE;
}
public String encrypt(String plaintext, String salt) throws NoSuchAlgorithmException,
UnsupportedEncodingException {
MessageDigest messageDigest = MessageDigest.getInstance(ALGORITHM);
messageDigest.reset();
messageDigest.update(salt.getBytes());
byte[] btPass = messageDigest.digest(plaintext.getBytes("UTF-8"));
for (int i = 0; i < ITERATIONS; i++) {
messageDigest.reset();
btPass = messageDigest.digest(btPass);
}
String encodedPassword = byteToBase64(btPass);
return encodedPassword;
}
private String byteToBase64(byte[] bt) throws UnsupportedEncodingException {
return new String(Base64.encodeBase64(bt));
}
包ereg.security.userdetails;
公共类LoggedUser扩展了用户{
私有静态最终长serialVersionUID=1L;
私有最终字符串id;
私人最终字符串imie;
私人最终字符串纳兹维斯科;
私人最终角色;
私人日期LastSuccessfullLogin;
私有字符串lastKnowIpAddress;
public LoggedUser(字符串用户名、字符串密码、布尔值启用、布尔值帐户未启用、,
boolean CredentialsNoExpired,boolean accountNonLocked,
收集实际上,这是有效的:
public String encrypt(String plaintext, String salt) throws NoSuchAlgorithmException,
UnsupportedEncodingException {
String pass = plaintext + "{" + salt + "}";
MessageDigest messageDigest = MessageDigest.getInstance(ALGORITHM);
messageDigest.reset();
byte[] btPass = messageDigest.digest(pass.getBytes("UTF-8"));
for (int i = 0; i < ITERATIONS - 1; i++) {
messageDigest.reset();
btPass = messageDigest.digest(btPass);
}
String hashedPass = new BigInteger(1, btPass).toString(16);
if (hashedPass.length() < 32) {
hashedPass = "0" + hashedPass;
}
return hashedPass;
}
publicstringencrypt(字符串明文、字符串salt)抛出NoSuchAlgorithmException,
不支持的编码异常{
字符串传递=纯文本+“{+salt+”}”;
MessageDigest=MessageDigest.getInstance(算法);
messageDigest.reset();
byte[]btPass=messageDigest.digest(pass.getBytes(“UTF-8”);
对于(int i=0;i
有人能告诉我为什么吗?我的意思是为什么当我尝试使用update(salt)方法时,它不起作用,当我切换到concate字符串时,它起作用了。我不介意用“{salt}”分开,因为这只允许我生成与spring完全相同的散列。问题是,在它生成错误的散列之前,即使使用给定的salt。我使用sha256生成器进行了检查。有人能告诉我为什么它在字符串合并后开始工作吗?数据库版本是如何生成的?对不起,我忘了添加它。请查看更新d问题你试过不加盐吗?把它拿出来,这样你就少了运动部件,让它工作起来。一旦你适应了,再把盐加进去。感谢digitaljoel的提示。没有盐也不行。事实上,我发现:byte[]btPass=messageDigest.digest(plaintext.getBytes(“UTF-8”);用于(inti=0;i