Cas Password + Salt修改说明


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>




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值