Shior 框架进阶(三)
----------自定义认证Realm
在之前的博文当中我们对shrio的基本概念进行了说明,并对shiro的一个基本的流程进行的分析,以及手工的测试,
但是咋实际上,我们用来比较的账户信息是在数据库当中读取出来的,而在shiro当中读取用户信息的类就是这个AuthorizingRealm类,在这个另外i当中有两个方法一个是认证doGetAuthenticationInfo,一个是授权doGetAuthorizationInfo;
接下来我们来测试这个认证的方法:
1、数据源配置:ini shirorealm.ini 中指定自定义数据源
同样在这里我们用ini文件来配置数据源,但是我们不是在像上次一样去直接在里面写密码
而是在里面指明我们自定义的Realm去实现账户信息的比对,这样你在加载配置文件得时候回去我们定义得类当中去去读取用户名和密码,相当于做的就是再数据库当中读取密码
下面就是代码:
[main]
#自定义 realm,下面定义了一个变量它指向的就是我们实现类的全名称
customRealm=com.ww.realm.CustomRealm
#将realm设置到securityManager,相当 于spring中注入
securityManager.realms=$customRealm
2、编写自定义数据源类
我们来验证认证,所以在这里实现的是AuthenticatingRealm这个类
public class CustomRealm extends AuthenticatingRealm{
/**
* 用于认证
* @param authenticationToken
* @return
* @throws AuthenticationException
*/
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//已知的正确的用户名和密码
//同样在这里我们不去写Dao层,读取数据源,在后面将它整合的时候,回去读取
String username = "Sulliven";
String password = "123456";
//获取用户输入:用户名
//在这里我们可以看到方法参数标为蓝色的变量,这个变量其实就是我们在shiro对外的api—//subject这个接口里面提交的Token也就是UsernamePasswordToken
//在这里获取传递过来的账户信息的方式有两种,一种就是将authenticationToken直接//强制转换成UsernamePasswordToken用这个类提供的get方法类获取相应的帐户名和密码
//方法是getUserName(),getPassword,在这里我们使用另外的一种方法
// getPrincipal一般就是得到用户名的方法直接将其转化为Stringji即可
String inputUsername = (String)authenticationToken.getPrincipal();
//拿到用户名之后我们手动比较用户名是否争取
//实际上,当用户名传递到这儿的时候,会根据你传递过来的用户名去在数据库当中查找密码,
//有些人肯定会问?那万一有账户名么密码一样的账户呢?
//其实shiro内部是由自己的加密机制的,而且是不可你的,就是将你的密码在转换的基础之上加//入了盐(slat)的概念,使得每一个用户对应的密码是不一样的,即使是你的用户名一样
//这些我们后面的更新也会有说明,好接着看代码
if(!inputUsername.equals(username)){
throw new UnknownAccountException("用户不存在");
}
//获取用户输入:密码(用户凭证,如果这里不判断,那么会由后面的//SimpleAuthenticationInfo的构造方法进行自动认证)
//获取密码的方式与获取账户的方式不同的地方就是
//因为在subject端封装的时候存储的密码在UsernamePasswordToken内部是以字符数组的形象存储的,然后转为Object类,所以我们首先将其转换为字符数组然后再转换为String
String inputPassword =
New String((char[]) authenticationToken.getCredentials());
//判断密码
if(!inputPassword.equals(password)) {
throw new IncorrectCredentialsException("密码不正确");
}
//获取用认证信息
//注意:(1)username处可以传递任何正确的用户信息的形式,例如:用户名,用户对象等,主要是为了后续的用户授权中可以将这个值取出来
// 作进一步的信息获取或处理
// (2)password处传递的是数据库中存储的密码,不要传递用户输入的密码
//还有一种字段比较密码的方式,就是,将你获得的用户名作为标记,利用用户名称查到的密码作为参数,再加入盐,再加入当前realm的名字封装到shiro提供的一个类当中交给框架
//其中username这个标记将会传递给授权的方法使用,以便给当前用户授权
//注意的是:授权实在你认证成功之后 进行的
//获取我们当前realm的名字,这样当你用SimpleAuthenticationInfo将信息封装交给shiro的时候,shiro就能够找到我们的这个类用于认证之后的授权
String realName = this.getName();
SimpleAuthenticationInfo info =
new SimpleAuthenticationInfo(username, password, realName);
return info;
}
}
3、测试类中使用自定义数据源
测试的方法与之前博文一样
不同的只是你的配值文件改了,需要加载你新建的配置文件;
4、身份验证的基本流程
下面我们来总结一下整个身份验证的基本流程:
(1)收集用户身份/凭证,即如用户名/密码
(2)调用subject.login进行登录,如果失败将返回相应的authenticationException异常, 根据异常提示用户错误信息;否则登录成功。
(3)创建自定义的Realm类,继承org.apache.shiro.realm.Authorizingrealm类, 实现doGetAuthenticationInfo()方法
以上就是shiro得认证,之后会对它的加盐加密方式进行简单得演示进行讲解,敬请期待!!!!!