一、散列算法
散列算法让其保证不可逆,安全。这里举一个例子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*/@Overridepublic 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*/@Overrideprotected 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*/@Overrideprotected 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.测试
@Testpublic 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());}
结果: