本项目中的自定义加和登录验证中的加密方法使用了shiro,记得加shiro-all-XXX.jar。
实现PasswordEncoder接口,public String encode(String password)返回加密后的密码。
1、实现PasswordEncoder接口
package org.jasig.cas.web.pass;
import javax.validation.constraints.NotNull;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.jasig.cas.authentication.handler.PasswordEncoder;
/**
* @author 74790
* 2018年11月13日20:16:47
* 自定义加密方式
*/
public class MyPassWord implements PasswordEncoder{
@NotNull
private Integer iterationCount; //加密次数
@Override
public String encode(String password) {
System.out.println("加密之前的密码:"+password);
String newpass = getNewPass(password, "salt", "MD5", 1024).toString();
System.out.println("加密之后的密码:"+newpass);
return newpass;
}
//自定义加密方式,返回加密后的密码字符串
private Object getNewPass(String password,String userName, String encryMode, Integer encryNum){
Object salt = ByteSource.Util.bytes(userName);
Object result = new SimpleHash(encryMode, password, salt, encryNum);
return result;
}
public Integer getIterationCount() {
return iterationCount;
}
public void setIterationCount(Integer iterationCount) {
this.iterationCount = iterationCount;
}
}
2、在deployerConfigContext.xml中配置自定义加密方式
1024
3、将默认的认证方式按照下面要求修改,配置数据源可以看本文章头部的CAS服务搭建教程
将
换成:
这里已经实现了自定义的加密方式,但是这个PasswordEncoder接口里面的public String encode(String password)方法不能传入盐值,如果没有盐值,两个用户一样的密码时,加密后的密码就会一样。所以此处需要盐值加密。可以看下面的自定义登录验证。
1、继承AbstractJdbcUsernamePasswordAuthenticationHandler类,重写authenticateUsernamePasswordInternal方法。
package com.mfc.handler;
import javax.validation.constraints.NotNull;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.handler.AuthenticationException;
import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
/**
* @author 74790
* 自定义登录方式
*/
public class MyQueryDatabaseAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {
@NotNull
private String sql; //查询sql
@NotNull
private String encryMode; //加密方式
@NotNull
private Integer encryNum; //加密次数
@Override
protected boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials credentials)
throws AuthenticationException {
final String username = getPrincipalNameTransformer().transform(credentials.getUsername());
final String password = credentials.getPassword();
final String encryptedPassword = getPasswordEncoder1(password, username, this.encryMode, this.encryNum);
try {
System.out.println("===页面输入密码加密后:"+encryptedPassword);
final String dbPassword = getJdbcTemplate().queryForObject(this.sql, String.class, username);
return dbPassword.equals(encryptedPassword);
} catch (final IncorrectResultSizeDataAccessException e) {
// this means the username was not found.
return false;
}
}
//自定义加密方式,返回加密后的密码字符串
private String getPasswordEncoder1(String password,String userName, String encryMode, Integer encryNum){
Object salt = ByteSource.Util.bytes(userName);
Object result = new SimpleHash(encryMode, password, salt, encryNum);
return result.toString();
}
/**
* @param sql The sql to set.
*/
public void setSql(final String sql) {
this.sql = sql;
}
public void setEncryMode(final String encryMode) {
this.encryMode = encryMode;
}
public void setEncryNum(final Integer encryNum){
this.encryNum = encryNum;
}
}
2、在deployerConfigContext.xml修改配置
将
修改成自定义的登录验证方式:
到此可以实现自定义登录验证。