您的位置:首页 > 其它

shiro教程2(自定义Realm)

2019-01-24 18:53 106 查看

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

自定义Realm的实现

创建自定义Realmjava类

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

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

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

/**
* 授权方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
return null;
}
}
方法名 说明
doGetAuthenticationInfo 完成账号==认证==的方法
doGetAuthorizationInfo 完成用户==授权==的方法

配置ini.xml文件

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

测试

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

@Test
public void test() {
// 1.获取SecurityManager工厂对象
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
// 2.通过Factory对象获取SecurityManager对象
SecurityManager securityManager = factory.getInstance();
// 3.将SecurityManager对象添加到当前运行环境中
SecurityUtils.setSecurityManager(securityManager);

// 4.获取Subject对象
Subject subject = SecurityUtils.getSubject();
AuthenticationToken token = new UsernamePasswordToken("root1", "12345");
// 登录操作
try {
subject.login(token);
} catch (UnknownAccountException e) {
System.out.println("账号出错...");
} catch(IncorrectCredentialsException e){
System.out.println("密码出错...");
}
// 获取登录的状态
System.out.println(subject.isAuthenticated());
}

原理分析

为什么要继承AuthorizingRealm?

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


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

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

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

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

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


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: