shiro教程2(自定义Realm)

通过shiro教程1我们发现仅仅将数据源信息定义在ini文件中与我们实际开发环境有很大不兼容,所以我们希望能够自定义Realm。

自定义Realm的实现

创建自定义Realmjava类

创建一个java文件继承AuthorizingRealm类,重写两个抽象方法

/**
* 自定义的Realm
* @author dengp
*
*/
public class MyRealm extends AuthorizingRealm{

\t/**
\t * 认证方法
\t * @param token
\t * \t就是我们在测试代码中 定义的UsernamePasswordToken对象
\t * 有我们保存的需要验证的账号密码信息
\t */
\t@Override
\tprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
\t\t// 获取账号信息
\t\tString principal = (String) token.getPrincipal();
\t\t// 正常逻辑此处应该根据账号去数据库中查询,此处我们默认账号为 root 密码123456
\t\t// 验证账号
\t\tif(!"root".equals(principal)){
\t\t\t// 账号错误
\t\t\treturn null;
\t\t}
\t\tString pwd = "123456";
\t\t// 验证密码
\t\tAuthenticationInfo info = new SimpleAuthenticationInfo(principal, pwd,"myrealm");
\t\treturn info;
\t}
\t
\t/**
\t * 授权方法

\t */
\t@Override
\tprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
\t\t// TODO Auto-generated method stub
\t\treturn null;
\t}
}
shiro教程2(自定义Realm)

配置ini.xml文件

[main]
#自定义 realm
customRealm=com.dpb.realm.MyRealm
#将realm设置到securityManager
securityManager.realms=$customRealm

测试

测试代码和上个案例一模一样

@Test
public void test() {
\t// 1.获取SecurityManager工厂对象
\tFactory<securitymanager> factory =
\t\t\tnew IniSecurityManagerFactory("classpath:shiro.ini");
\t// 2.通过Factory对象获取SecurityManager对象
\tSecurityManager securityManager = factory.getInstance();
\t// 3.将SecurityManager对象添加到当前运行环境中
\tSecurityUtils.setSecurityManager(securityManager);
\t
\t// 4.获取Subject对象
\tSubject subject = SecurityUtils.getSubject();
\tAuthenticationToken token = new UsernamePasswordToken("root1", "12345");
\t// 登录操作
\ttry {
\t\tsubject.login(token);
\t} catch (UnknownAccountException e) {
\t\tSystem.out.println("账号出错...");
\t} catch(IncorrectCredentialsException e){
\t\tSystem.out.println("密码出错...");
\t}
\t// 获取登录的状态
\tSystem.out.println(subject.isAuthenticated());
}/<securitymanager>
shiro教程2(自定义Realm)

shiro教程2(自定义Realm)

shiro教程2(自定义Realm)

原理分析

为什么要继承AuthorizingRealm?

上个教程中我们完整的分析了认证的流程,我们发现在认证的过程核心代码是此:

shiro教程2(自定义Realm)

核心方法是doGetAuthenticationInfo(token)
在Realm的结构中

shiro教程2(自定义Realm)

AuthorizingRealm和AuthenticatingRealm都提供的有doGetAuthenticationInfo (token) 的抽象方法。但是AuthenticatingRealm中要重写的抽象方法太多而AuthorizingRealm只需要重写两个方法,且这两个方法都是我们需要使用的。故选择继承AuthorizingRealm

自定义的Realm什么时候被调用的?

shiro教程2(自定义Realm)

密码验证什么时候执行的?

注意:自定义Realm中只完成了账号的认证。密码认证还是在AuthenticatingRealm中完成的,只是我们在自定义Realm中完成了密码的设置。

shiro教程2(自定义Realm)

shiro教程2(自定义Realm)

shiro教程2(自定义Realm)


分享到:


相關文章: