一、散列算法
散列算法让其保证不可逆,安全。这里举一个例子sh1的摘要算法。上代码
/**
* 散列算法
* @author Administrator
*/
public class HashRsaUtil {
/**
* 加密方式
*/
public static final String SHA1="SHA-1";
/**
* 加密次数
*/
public static final Integer ITERATIONS=512;
/**
* sh1摘要算法
* @param input 传入的参数
* @param salt 干扰素(加盐)
* @return
*/
public static String sha1(String input, String salt){
return new SimpleHash(SHA1,input,salt,ITERATIONS).toString();
}
/**
* 随机生成salt
* @return 返回一个hex编码的salt
*/
public static String generateSalt(){
SecureRandomNumberGenerator generator = new SecureRandomNumberGenerator();
return generator.nextBytes().toHex();
}
/**
* 铭文加密返回密文格式
* @param inscription 要加密的铭文
* @return 返回salt和密文
*/
public static Map<String,String> encryptInscription( String inscription){
Map<String,String> map = new HashMap<>(16);
String salt = generateSalt();
String ciphertext = sha1(inscription, salt);
map.put("salt",salt);
map.put("ciphertext",ciphertext);
return map;
}
二、Remal使用散列算法
1.修改service模拟数据库出来的数据
/**
* 模拟数据库出来的数据
* 将123转成密文
* @param userName
* @return
*/
@Override
public Map<String, String> findPasswordByName(String userName) {
return HashRsaUtil.encryptInscription("123");
}
2.修改自定义的remal
package com.example.config;
import com.example.service.impl.SecurityServiceImpl;
import com.example.untils.HashRsaUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
* 自定义的realm
* 继承授权的接口
*
* @author Administrator
*/
public class DefinitionRealm extends AuthorizingRealm {
/**
* 鉴权
*
* @param principalCollection
* @return
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null;
}
/**
* 指定完比较器之后还需要修改比较器,因为当前使用的还是默认的
* 比较器,需要改成咱们自己的比较器
*/
public DefinitionRealm(){
//指定密码匹配方式has1
//使用Hashed密码比较器
//指定算法
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(HashRsaUtil.SHA1);
//指定密码迭代次数
matcher.setHashIterations(HashRsaUtil.ITERATIONS);
//使用父层方法使匹配方式生效,将我们指定的比较器写进去
setCredentialsMatcher(matcher);
}
/**
* 认证
*
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//获取登录名
String principal = (String) authenticationToken.getPrincipal();
//然后模拟用登录名去数据库拿到密码
SecurityServiceImpl securityService = new SecurityServiceImpl();
//获取密文密码
Map<String, String> map = securityService.findPasswordByName(principal);
//判断拿到的密码是否为空
if (StringUtils.isEmpty(map)) {
throw new UnknownAccountException("该用户不存在!");
}
String salt = map.get("salt");
String password = map.get("ciphertext");
return new SimpleAuthenticationInfo(principal, password, ByteSource.Util.bytes(salt), getName());
}
}
3.测试
@Test
public void shiroLoginTest() {
//导入ini配置创建工厂
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//工厂构建安全管理器
SecurityManager securityManager = factory.getInstance();
//使用工具生效安全管理器
SecurityUtils.setSecurityManager(securityManager);
//使用工具获取subject的主体
Subject subject = SecurityUtils.getSubject();
//构建账号密码
UsernamePasswordToken passwordToken = new UsernamePasswordToken("zhangSan", "123");
//使用subject主体去登录
subject.login(passwordToken);
//打印登录信息
System.out.println("登录结果" + subject.isAuthenticated());
}
结果: