Cas Password + Salt修改说明:
之前想参考http://www.cnblogs.com/leefreeman/archive/2012/12/05/2802556.html#2760594
这片文章的做法,但是对于如何从数据库中获取salt的做法没有找到怎么做,所以最后采用了下面描述的另一种方式:
添加以下接口:
org.jasig.cas.util.PasswordSaltEncoder
package org.jasig.cas.util;
publicinterface PasswordSaltEncoder{
String encode(String password, String saltBase64);
}
添加以下类:
org.jasig.cas.util.QueryDatabaseAuthenticationHandlerWithSalt
package org.jasig.cas.util;
import java.util.Map;
import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import javax.validation.constraints.NotNull;
public class QueryDatabaseAuthenticationHandlerWithSalt
extends AbstractJdbcUsernamePasswordAuthenticationHandler {
private static Logger log = LoggerFactory.getLogger(
QueryDatabaseAuthenticationHandlerWithSalt.class);
@NotNull
private String sql;
@NotNull
private String passwordColumnName;
@NotNull
private String saltColumnName;
@NotNull
private PasswordSaltEncoder passwordSaltEncoder;
@Override
protected final boolean authenticateUsernamePasswordInternal(
final UsernamePasswordCredentials credentials)
throws AuthenticationException {
final String username = getPrincipalNameTransformer().transform(
credentials.getUsername());
final String password = credentials.getPassword();
try {
final Map<String, Object> dataMap = getJdbcTemplate().queryForMap(
this.sql, username);
if(log.isDebugEnabled()){
for(String key : dataMap.keySet()){
log.debug("Key: {}, Value: {}", key, dataMap.get(key));
}
}
String saltBase64 = (String) dataMap.get(saltColumnName);
String dbPassword = (String) dataMap.get(passwordColumnName);
String encryptedPassword = this.getPasswordSaltEncoder().encode(
password, saltBase64);
log.debug("db: {}, encrypt: {}", dbPassword, encryptedPassword);
return dbPassword.equals(encryptedPassword);
} catch (final IncorrectResultSizeDataAccessException e) {
// this means the username was not found.
return false;
}
}
public void setSql(final String sql) {
this.sql = sql;
}
public void setPasswordColumnName(final String passwordColumnName) {
this.passwordColumnName = passwordColumnName;
}
public void setSaltColumnName(final String saltColumnName) {
this.saltColumnName = saltColumnName;
}
public void setPasswordSaltEncoder(PasswordSaltEncoder passwordSaltEncoder){
this.passwordSaltEncoder = passwordSaltEncoder;
}
public PasswordSaltEncoder getPasswordSaltEncoder(){
return this.passwordSaltEncoder;
}
}
org.jasig.cas.util.SHA512PasswordEncoder
package org.jasig.cas.util;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.jasig.cas.authentication.handler.PasswordEncoder;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.util.ByteSource;
public class SHA512PasswordEncoder implements PasswordSaltEncoder {
private int iterationCount;
public int getIterationCount() {
return iterationCount;
}
public void setIterationCount(int iterationCount) {
this.iterationCount = iterationCount;
}
public static void main(String[] args) {
String password = "1234567890abcdefg";
ByteSource salt = new SecureRandomNumberGenerator().nextBytes(64);
long t1 = System.currentTimeMillis();
new Sha512Hash(password, salt, 1000).toBase64();
long t2 = System.currentTimeMillis();
new Sha512Hash(password, salt, 1).toBase64();
long t3 = System.currentTimeMillis();
System.out.println("Iteration count: 1000, TimeMillis: " + (t2 - t1));
System.out.println("Iteration count: 1, TimeMillis: " + (t3 - t2));
}
@Override
public String encode(String password, String saltBase64) {
ByteSource salt = ByteSource.Util.bytes(Base64.decode(saltBase64));
return new Sha512Hash(password, salt, iterationCount).toBase64();
}
}
src/main/webapp/WEB-INF/deployerConfigContext.xml文件中修改:
<beanid="authenticationManager"class="org.jasig.cas.authentication.AuthenticationManagerImpl">
...
<propertyname="authenticationHandlers">
<list>
...
<bean
class="org.jasig.cas.util.QueryDatabaseAuthenticationHandlerWithSalt">
<propertyname="dataSource"ref="dataSource"></property>
<propertyname="passwordColumnName"value="loginPasswd"></property>
<propertyname="saltColumnName"value="salt"></property>
<propertyname="sql"
value="select loginPasswd, salt from um_login where loginName=?"></property>
<propertyname="passwordSaltEncoder"ref="SH512PasswordEncoder"></property>
<!--保存的密码+salt SHA512加密-->
</bean>
</list>
</property>
</bean>
<beanid="SH512PasswordEncoder"
class="org.jasig.cas.util.SHA512PasswordEncoder">
<propertyname="iterationCount">
<value>1000</value>
</property>
</bean>