一、项目说明
项目环境:jdk1.7+tomcat7+idea2018+maven+shiro1.3.2
源代码github地址:https://github.com/tmAlj/shiro/tree/master/ssms
实现目标:通过指定加密算法以及加盐,完成整个认证流程
综合实例:基于shiro的按钮级别的权限管理系统
二、不加盐值加密验证
注:本节所有实例基于shiro学习笔记六:shiro认证流程
(1)创建自定义Realm,名称为EncrRealm
package com.wsd.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
/**
* Created by tm on 2018/8/17.
* 自定义加密认证realm
*/
public class EncrRealm extends AuthenticatingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//token类型转化
UsernamePasswordToken upToken = (UsernamePasswordToken)authenticationToken;
//获取前台用户信息
String username = upToken.getUsername();
// TODO 从数据库中获取用户信息,这里先模拟从数据库获取数据
// 使用数据库中的用户信息与前台传入的用户信息比对,如果用户不存在,抛出异常
if("wsd".equals(username)) {
throw new UnknownAccountException("==================用户不存在");
}
// 用户被锁定是,抛出异常
if("wsd1".equals(username)) {
throw new LockedAccountException("==================用户被锁定");
}
// TODO 从数据库中获取用户信息,这里先模拟从数据库获取数据
Object principal = username; //从数据中获取用户名称
Object credentials = "4a95737b032e98a50c056c41f2fa9ec6"; //从数据中获取用户密码,这里的值是通过加密工具类加密所得
String realmName = "encrRealm"; //自定义
return new SimpleAuthenticationInfo(principal, credentials, realmName);
}
}
(2)配置自定义EncrRealm
注:在spring-shiro-config.xml中配置自定义realm,指定加密算法以及加密次数等
<!-- 配置shiro的核心securityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<!--<property name="sessionMode" value="native"/>-->
<!-- <property name="realm" ref="jdbcRealm"/>-->
<property name="realm" ref="encrRealm"/>
<!--<property name="realm" ref="saltRealm"/>-->
</bean>
<!-- 配置加密Realm -->
<bean id="encrRealm" class="com.wsd.shiro.EncrRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 指定加密方式MD5,SHA1等 -->
<property name="hashAlgorithmName" value="MD5"></property>
<!-- 指定加密次数 -->
<property name="hashIterations" value="10"></property>
</bean>
</property>
</bean>
(3)密码加密
注:这里为了方便测试,自己对原始密码加密,放到EncrRealm中进行认证
/*不加盐md5加密*/
public static void md5(){
//加密方式
String hashAlgorithmName = "MD5";
//源密码
Object credentials = "123456";
//盐值
Object salt = null;
//加密次数
int hashIterations = 10;
Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
System.out.println(result);
}
(4)测试示例
说明:登录页面随便输入用户名称,如果密码为123456可登录成功,其他则失败,说明加密成功
三、加盐值加密验证
注:盐值一般为唯一值,如用户名,身份证号等,主要为了解决由于多用户密码相同时加密后密码相同问题,加盐后的密码会为唯一值
(1)创建自定义Realm,名称为SaltRealm
package com.wsd.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.util.ByteSource;
/**
* Created by tm on 2018/8/17.
* 自定义加盐加密认证realm
*/
public class SaltRealm extends AuthenticatingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//token类型转化
UsernamePasswordToken upToken = (UsernamePasswordToken)authenticationToken;
//获取前台用户信息
String username = upToken.getUsername();
// TODO 从数据库中获取用户信息,这里先模拟从数据库获取数据
// 使用数据库中的用户信息与前台传入的用户信息比对,如果用户不存在,抛出异常
if("wsd".equals(username)) {
throw new UnknownAccountException("==================用户不存在");
}
// 用户被锁定是,抛出异常
if("wsd1".equals(username)) {
throw new LockedAccountException("==================用户被锁定");
}
//加盐测试用户
Object credentials = null;
if ("wsd2".equals(username)) {
credentials = "b65f57fd1dcbafdb1c05295356a41edf"; //这里的值是通过加密工具类加密所得
} else if ("wsd3".equals(username)) {
credentials = "2d68497b78547e6b0bc6a6c1bb22fb44";
}
// TODO 从数据库中获取用户信息,这里先模拟从数据库获取数据
String realmName = getName();
ByteSource credentialsSalt = ByteSource.Util.bytes(username);
Object principal = username; //从数据中获取用户名称
return new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
}
}
(2)配置自定义SaltRealm
注:在spring-shiro-config.xml中配置自定义realm,指定加密算法以及加密次数等
<!-- 配置shiro的核心securityManager -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"/>
<!--<property name="sessionMode" value="native"/>-->
<!-- <property name="realm" ref="jdbcRealm"/>-->
<!-- <property name="realm" ref="encrRealm"/>-->
<property name="realm" ref="saltRealm"/>
</bean>
<!-- 配置加盐加密Realm -->
<bean id="saltRealm" class="com.wsd.shiro.SaltRealm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 指定加密方式MD5,SHA1等 -->
<property name="hashAlgorithmName" value="MD5"></property>
<!-- 指定加密次数 -->
<property name="hashIterations" value="10"></property>
</bean>
</property>
</bean>
(3)密码加密
注:这里为了方便测试,自己对原始密码加盐加密,放到SaltRealm中进行认证
/*加盐md5加密*/
public static void md5AndSalt(){
String hashAlgorithmName = "MD5";
Object credentials = "123456";
//盐值一般为唯一值,如用户名,手机号等
Object salt = null;
// salt = ByteSource.Util.bytes("wsd2");
salt = ByteSource.Util.bytes("wsd3");
int hashIterations = 10;
Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
System.out.println(result);
}
(4)测试示例
说明:登录页面随便输入用户名称,如果密码为123456可登录成功,其他则失败,说明加密成功