一、项目说明
项目环境:jdk1.7+tomcat7+idea2018+maven+shiro1.3.2
源代码github地址:https://github.com/tmAlj/shiro/tree/master/ssms
实现目标:创建多个Realm,并指定验证策略,完成验证
综合实例:基于shiro的按钮级别的权限管理系统
二、Realm认证
注:这里实现的效果是,通过创建两个realm,并实现对密码的不同加密方式,最后使用AllSuccessfulStrategy认证策略完成认证,本节所有实例基于shiro学习笔记七:shiro加密认证
(1)自定义Realm,名称为Md5Realm
package com.wsd.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
/**
* Created by tm on 2018/8/18.
* 自定义md5加密认证realm,实现多realm认证
*/
public class Md5Realm extends AuthenticatingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//token类型转化
UsernamePasswordToken upToken = (UsernamePasswordToken)authenticationToken;
//获取前台用户信息
String username = upToken.getUsername();
// TODO 从数据库中获取用户信息,这里先模拟从数据库获取数据
Object principal = username; //从数据中获取用户名称
Object credentials = "4a95737b032e98a50c056c41f2fa9ec6"; //从数据中获取用户密码,这里的值是通过加密工具类加密所得
String realmName = "md5Realm"; //自定义
return new SimpleAuthenticationInfo(principal, credentials, realmName);
}
}
(2)自定义Realm,名称为Sha1Realm
package com.wsd.shiro;
import org.apache.shiro.authc.*;
import org.apache.shiro.realm.AuthenticatingRealm;
/**
* Created by tm on 2018/8/18.
* 自定义sha1加密认证realm,实现多realm认证
*/
public class Sha1Realm extends AuthenticatingRealm {
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//token类型转化
UsernamePasswordToken upToken = (UsernamePasswordToken)authenticationToken;
//获取前台用户信息
String username = upToken.getUsername();
// TODO 从数据库中获取用户信息,这里先模拟从数据库获取数据
Object principal = username; //从数据中获取用户名称
Object credentials = "ab0cab93525895d802494fe858ca21378fd8e3ee"; //从数据中获取用户密码,这里的值是通过加密工具类加密所得
String realmName = "sha1Realm"; //自定义
return new SimpleAuthenticationInfo(principal, credentials, realmName);
}
}
(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);
}
/*不加盐sha1加密*/
public static void sha1(){
//加密方式
String hashAlgorithmName = "SHA1";
//源密码
Object credentials = "123456";
//盐值
Object salt = null;
//加密次数
int hashIterations = 10;
Object result = new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations);
System.out.println(result);
}
(2)配置自定义Realm
注:在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"/>-->
<!-- 指定认证策略 -->
<property name="authenticator" ref="authenticator"></property>
<!-- 配置多Realm -->
<property name="realms">
<list>
<ref bean="md5Realm"/>
<ref bean="sha1Realm"/>
</list>
</property>
</bean>
<!-- 配置多Realm认证策略 -->
<bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
<property name="authenticationStrategy">
<!-- 所有Realm验证成功才算成功,且返回所有Realm身份验证成功的认证信息,如果有一个失败就失败了。-->
<bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"></bean>
<!-- 只要有一个Realm验证成功即可,和FirstSuccessfulStrategy不同,返回所有Realm身份验证成功的认证信息,该策略为默认策略 -->
<!--<bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>-->
<!-- 只要有一个Realm验证成功即可,只返回第一个Realm身份验证成功的认证信息,其他的忽略 -->
<!--<bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy"></bean>-->
</property>
</bean>
<!-- 配置多Realm加密Realm -->
<bean id="md5Realm" class="com.wsd.shiro.Md5Realm">
<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>
<!-- 配置多Realm加密Realm -->
<bean id="sha1Realm" class="com.wsd.shiro.Sha1Realm">
<property name="credentialsMatcher">
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 指定加密方式MD5,SHA1等 -->
<property name="hashAlgorithmName" value="SHA1"></property>
<!-- 指定加密次数 -->
<property name="hashIterations" value="10"></property>
</bean>
</property>
</bean>
(3)测试示例
说明:通过在spring-shiro-config.xml文件中改变认证策略测试,如AllSuccessfulStrategy需要在两个realm中的密码都匹配才能通过验证,AtLeastOneSuccessfulStrategy只需要任意一个realm中密码匹配即可通过验证等