Realm就是从数据库里获取数据进行登录用户和密码的认证对比工作。
在复杂项目中,很可能会出现,登录认证的用户数据,来自另一个数据表,有时甚至不在一个数据库,这种情况下就需要多个Realm进行登录认证。
从前面跟踪subject.login(token);方法的源码,其实就可以发现shiro是支持多个Realm的。ModularRealmAuthenticator 类
简单模拟掌握多个 Realm 使用知识点,具体实现认证工作省略。
1、自定义Realm新建几个:
上篇文章有一个数据库登录认证的 ShiroRealm, 然后模拟再新建两个。
public class QQRealm extends AuthenticatingRealm{
/**
* 处理登录认证方法
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("QQRealm");
AuthenticationInfo info = new SimpleAuthenticationInfo("123", "123456", null, getName()); //随便写的,防止NullPointerException异常
return info;
}
}
public class WeixinRealm extends AuthenticatingRealm{
/**
* 处理登录认证方法
* @param token
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("WeixinRealm");
AuthenticationInfo info = new SimpleAuthenticationInfo("456", "123456", null, getName());
return info;
}
}
2、spring.xml 配置
1)配置自己域的Realm
2) shiro 的核心组件:securityManager 中注入,然后再配置 authenticator 属性
注意:
1)realms 是list属性,点进去看源码,同时 list 中ref(其顺序为访问顺序)引用 Realm 顺序决定登录先访问那个 Realm.
2)authenticator属性必须在 realms 属性之前。
3、运行项目访问登录即可
结论:
1)当有多个Realm类登录认证时,每个Realm都会去进行一次登录认证,它们各自是不会去管其他的Realm认证结果
2)默认情况下,多个Realm进行登录认证时,只要有一个Realm登录认证通过,整个的登录认证就会通过
1)FirstSuccessfulStrategy:第一个Realm验证成功就登录成功
2)AtLeastOneSuccessfulStrategy:至少有一个Realm验证成功就登录成功(默认策略)
3)AllSuccessfulStrategy,全部的Realm验证必须都成功,则登录成功
1、配置登录认证策略
修改默认策略为 第三种 AllSuccessfulStrategy
其他不用修改,MyCredentialsMatcher1 和 MyCredentialsMatcher1 两个自定义密码验证类相同,都返回true 认证成功。
public class MyCredentialsMatcher1 extends SimpleCredentialsMatcher{
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
return true;
}
}
2、运行项目访问登录即可
此时,只用 之前写的表单登录 ShiroRealm 认证成功,则全部认证成功。测试ok
end ~