利用MD5加密密码算法——其中Md5Hash传入三个参数,可以直接只传密码,但是简单的密码容易被穷举出来,于是有了参数二:盐值(利用随机盐值与密码一起加密);参数三:散列次数
public class MD5Utils {
public static Md5Hash MD5(String pwd,String salt){
//散列1024次
Md5Hash hash = new Md5Hash(pwd,salt,1024);
System.out.println(hash);
return hash;
}
}
模拟数据库:
doGetAuthenticationInfo:认证过程——获取需要认证的信息 ,模拟从数据库取出用户账号,进行对比,如果对比通过则说明该用户存在,继续对比密码:将传入的密码进行加密与数据库存入的密码进行对比
doGetAuthorizationInfo:授权过程——首先获取用户信息 认证,模拟从数据库中获取该用户的角色和操作权限,加入该用户中
public class CustomerRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//授权
String principal = (String) principalCollection.getPrimaryPrincipal();
System.out.println("身份信息"+principal);
SimpleAuthorizationInfo info = null;
//
if(principal.equals("yinjinhui")){
info = new SimpleAuthorizationInfo();
info.addRole("user");
info.addRole("admin");
}
if(principal.equals("wangtingting")){
info = new SimpleAuthorizationInfo();
info.addRole("login");
//赋予操作权限(可将数据库查询出来)——————例如:对01用户所有的操作
info.addStringPermission("user:*:01");
}
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//认证
String principal = (String)authenticationToken.getPrincipal();
if("wangtingting".equals(principal)){
//1.数据库中登录账号 2.数据库中登录密码 3.存入数据库前MD5加密时的盐 4.realm的名字
SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
"wangtingting",
MD5Utils.MD5("123","ee"),
ByteSource.Util.bytes("ee"),
this.getName());
return simpleAuthenticationInfo;
}
return null;
}
}
测试:
1.创建安全管理对象DefaultSecurityManager
2.设置Realm(设置自己定义的CustomerRealm,如果是自带的realm,对比的是ini配置文件)
3.设置realm使用hash凭证匹配器,设置md5加密匹配算法,因为存入数据库中是1024次散列,所以凭证匹配器设置setHashIterations为1024
4.SecurityUtils给全局安全工具类设安全管理器
5.获取主题Subject
6.获取登录用户的令牌(账号密码)
public class TestCustomerRealmAuthenticator {
public static void main(String[] args) {
//1.创建安全管理对象
DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
//设置realm
CustomerRealm customerRealm =new CustomerRealm();
defaultSecurityManager.setRealm(customerRealm);
//设置realm使用hash凭证匹配器
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5");
//设置md5加密算法的散列值,因为匹配的密码是进行1024次散列的
matcher.setHashIterations(1024);
customerRealm.setCredentialsMatcher(matcher);
SecurityUtils.setSecurityManager(defaultSecurityManager);
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("wangtingting","123");
try{
System.out.println("认证前"+subject.isAuthenticated());
subject.login(token);//用户认证
System.out.println("认证后"+subject.isAuthenticated());
}catch (UnknownAccountException e){
System.out.println("用户不存在");
}catch (IncorrectCredentialsException e){
System.out.println("密码错误");
}catch (Exception e){
e.printStackTrace();
}
//判断该用户的角色权限
System.out.println("角色权限:"+subject.hasRole("user"));
//判断该用户的操作权限
System.out.println("操作权限:"+subject.isPermitted("user:u:01"));
}
}