我们先得到MD5加密后的字串
@Test
public void test01(){
//md5
Md5Hash md5Hash = new Md5Hash("123456");
System.out.println(md5Hash.toHex());//e10adc3949ba59abbe56e057f20f883e
}
@Test
public void test02(){
//md5+salt
Md5Hash hash = new Md5Hash("123456", "ABCDE");
System.out.println(hash.toHex());//8cdcdd77a21a5f80e3a88a013bc957f8
}
@Test
public void test03(){
//md5+salt+hash散列
Md5Hash hash = new Md5Hash("123456", "ABCDE",1024);
System.out.println(hash.toHex());//abadd954d2234843108de678396229e5
}
定义成一个类方便调用
public class Md5Enum {
/**
* 对"123456"直接md5结果
*/
public static final String HEX1 = "e10adc3949ba59abbe56e057f20f883e";
/**
* 对"123456",盐为"ABCDE"的md5结果
*/
public static final String HEX2 = "8cdcdd77a21a5f80e3a88a013bc957f8";
/**
* 对"123456",盐为"ABCDE",散列1024次的md5结果
*/
public static final String HEX3 = "abadd954d2234843108de678396229e5";
/**
* 盐值
*/
public static final String SALT="ABCDE";
}
一、只用md5不加盐的hash
1.写一个配置类
public class UserMd5Authenticator {
@Test
public void test() {
DefaultSecurityManager securityManager = new DefaultSecurityManager();
UserMd5Realm realm = new UserMd5Realm();
//使用hash凭证匹配器,默认是SimpleCredentialsMatcher
realm.setCredentialsMatcher(new HashedCredentialsMatcher("md5"));
securityManager.setRealm(realm);
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("荼白","123456");
try {
subject.login(token);
System.out.println("登录成功");
}catch (UnknownAccountException e){
e.printStackTrace();
}catch (IncorrectCredentialsException e){
e.printStackTrace();
}
}
}
2.自定义realm
public class UserMd5Realm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
if(username.equals("荼白")){
return new SimpleAuthenticationInfo(username,"Md5Enum.HEX1",getName());
}
return null;
}
}
运行后得到结果
二、使用md5加盐的hash
我们的这个类是和上面一样的
public class UserMd5Authenticator {
@Test
public void test() {
//和上面是一样的
//...
}
}
我们只需要修改自定义的Realm即可
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
public class UserMd5Realm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
if(username.equals("荼白")){
//参数分别为:数据库用户名,数据库md5+salt后的密码,注册时的随机盐,realm的名字
return new SimpleAuthenticationInfo(username,Md5Enum.HEX2
, ByteSource.Util.bytes(Md5Enum.SALT)
,getName());
}
return null;
}
}
运行结果
三、使用md5+salt+哈希散列
注:默认的散列次数是1次的
首先是配置类,只需要多加一行代码即可
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class UserMd5Authenticator {
@Test
public void test() {
DefaultSecurityManager securityManager = new DefaultSecurityManager();
UserMd5Realm realm = new UserMd5Realm();
//使用hash凭证匹配器,默认是SimpleCredentialsMatcher
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("md5");
//设置散列次数,这行是多加的
matcher.setHashIterations(1024);
realm.setCredentialsMatcher(matcher);
securityManager.setRealm(realm);
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("荼白","123456");
try {
subject.login(token);
System.out.println("登录成功");
}catch (UnknownAccountException e){
e.printStackTrace();
}catch (IncorrectCredentialsException e){
e.printStackTrace();
}
}
}
然后是自定义的Realm,和第二种一样,不需要改变
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
public class UserMd5Realm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
if(username.equals("荼白")){
//参数分别为:数据库用户名,数据库md5+salt后的密码,注册时的随机盐,realm的名字
return new SimpleAuthenticationInfo(username,Md5Enum.HEX3
, ByteSource.Util.bytes(Md5Enum.SALT)
,getName());
}
return null;
}
}
运行结果