上一个demo里的realm使用的自带的默认的,通常情况下我们都会使用自定义的realm
Shiro默认自带的 IniRealm,IniRealm从ini配置文件中读取用户信息,而大部分情况是从数据库中读取用户信息。所以需要实现自定义的realm
realm接口如下:
可以分析得出:
CathingRealm:负责缓存处理AuthenticationRealm:负责认证AuthorizingRealm:负责授权
通常情况,自定义的Realm继承AuthorizingRealm即可实现认证和授权
二、自定义realm的demo22.1 导shiro-jar包1.导shiro的jar包
2.自定义realm的类
3.写一个shiro测试类
//我自定义的realm连接器 (可以不使用ini文件)public class CustomerRealm extends AuthorizingRealm { //授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } //认证 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken YtyToken) throws AuthenticationException { System.out.println("进入到自定的realm连接器中------------");// Object principal = YtyToken.getPrincipal(); //正常会返回上面一个object对象,这里我不用,而是直接用String类型的name,所以需要强转,如下 String name = (String) YtyToken.getPrincipal(); //这个是获取用户信息 System.out.println(name); //进行用户信息的判断;就是判断token中的值 if ("yty".equals(name)){ //三个参数:1.用户姓名 2.用户密码 3.获取当前的realm对象 SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name,"password",getName()); //成功就返回当前对象 return simpleAuthenticationInfo; } //如果用户姓名和密码对应不上 返回null return null; }}
2.3 测试类CustomerTestpublic class CustomerTest { public static void main(String[] args) { //1.创建安全管理器 DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); //2.给安全管理器设置realm对象--把自定义的realm对象拿过来 defaultSecurityManager.setRealm(new CustomerRealm()); //3.安全工具设置安全管理器-即把安全管理器加入到安全工具中去 SecurityUtils.setSecurityManager(defaultSecurityManager); //4.通过安全工具获取主体subject //认证主体 Subject subject = SecurityUtils.getSubject();//5.设置令牌 //里面的参数就是前端获取过来的,我这里是写死的,正常不能这样子写 UsernamePasswordToken token = new UsernamePasswordToken("yty","password"); System.out.println("认证前-----------"); System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证 //开始认证 subject.login(token); System.out.println("认证后-----------"); System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证 }}
2.4 测试结果分析
由此分析上述demo整个流程都没有问题。
现在我将前端获取的用户姓名信息故意改错,然后测试
将用户名yty改错yty123
结果:报错。
所以还需要处理一下异常,直接报错是不行的。
直接将认证前后的代码放入try…catch试一试
public class CustomerTest { public static void main(String[] args) { //1.创建安全管理器 DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); //2.给安全管理器设置realm对象--把自定义的realm对象拿过来 defaultSecurityManager.setRealm(new CustomerRealm()); //3.安全工具设置安全管理器-即把安全管理器加入到安全工具中去 SecurityUtils.setSecurityManager(defaultSecurityManager); //4.通过安全工具获取主体subject //认证主体 Subject subject = SecurityUtils.getSubject();//5.设置令牌 //里面的参数就是前端获取过来的,我这里是写死的,正常不能这样子写 UsernamePasswordToken token = new UsernamePasswordToken("yty","PASSWORD"); try { System.out.println("认证前-----------"); System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证 //开始认证 subject.login(token); System.out.println("认证后-----------"); System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证 }catch (UnknownAccountException abc){ //UnknownAccountException是未知错误的异常 System.out.println("用户信息验证错误,请重新输入-------"); abc.printStackTrace(); }catch (IncorrectCredentialsException abc){ //IncorrectCredentialsException是账号密码错误的异常 System.out.println("用户账号或者密码,请重新输入-------"); abc.printStackTrace(); } }}
具体改动为:
//里面的参数就是前端获取过来的,我这里是写死的,正常不能这样子写 UsernamePasswordToken token = new UsernamePasswordToken("yty","PASSWORD"); try { System.out.println("认证前-----------"); System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证 //开始认证 subject.login(token); System.out.println("认证后-----------"); System.out.println("是否认证:"+subject.isAuthenticated());//判断是否有验证 }catch (UnknownAccountException abc){ //UnknownAccountException是未知错误的异常 System.out.println("用户信息验证错误,请重新输入-------"); abc.printStackTrace(); }catch (IncorrectCredentialsException abc){ //IncorrectCredentialsException是账号密码错误的异常 System.out.println("用户账号或者密码,请重新输入-------"); abc.printStackTrace(); }
然后测试:
然后保持用户名正确,密码password改为PASSWORD,测试:
根据不同的输入参数,即可得到对应的验证结果。
以上所有就是自定义realm的基本了解。