用来测试的实例代码
package com.baizhi.test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.junit.Test;
public class ShiroTestDemo {
/**
* 模拟用户输入的用户名和密码
*/
private String username = "zhangsan";
private String password = "123456";
@Test
public void test1() {
//1、获取配置文件中的数据,得到安全管理器工厂
IniSecurityManagerFactory securityManagerFactory = new IniSecurityManagerFactory("classpath:static/shiro.ini");
//2、获取安全管理器,安全管理器封装了配置文件数据【相当于得到数据库中所有的数据】
SecurityManager securityManager = securityManagerFactory.getInstance();
//把安全管理器给工具类 相当于Subject和安全管理器建立了联系
SecurityUtils.setSecurityManager(securityManager);
//3、获取Subject【通过工具类获取】->保证了在项目的任何位置获取到的对象都是同一个
Subject subject = SecurityUtils.getSubject();
//4、把用户输入的账号和密码给Subject对象 调用登录方法传入用户输入的账号密码[封装到token中]
//封装到令牌
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
/**
* login通过抛异常的方式 告诉用户有没有认证成功
* UnknownAccountException 不知道账号异常 账号错误
* IncorrectCredentialsException 不正确的密码 密码错误
*/
try {
subject.login(token);
System.out.println("登录成功");
} catch (Exception e) {
System.out.println("账号或密码错误");
}
/**
* isAuthenticated 查询当前主体的认证状态
* Authenticate 认证
*/
boolean authenticated = subject.isAuthenticated();
System.out.println(authenticated);
}
}
模拟数据库
shiro.ini文件
[users]
zhangsan=123456
lisi=123456
lilei=123456
lihua=123456
hanmm=123456
说明:因为要追踪身份令牌token的运行流程,这里在提交token的位置打断点
Debug模式运行
变量
调用安全管理器中login方法
认证方法
调用认证器里面的认证方法
做认证
Realm对象查询数据
获取认证信息
异常情况
如果
account
为
null
,则说明
token
为空,那么
doGetAuthenticationInfo(token)
获取到的认证数据也为
null
,返回的验证信息
info
为
null
,根据源码,如果
info==null
,抛出异常
throw new UnknownAccountException(msg)
.
结论
SimpleAccountRealm
类中默认实现了抽象类
AuthenticatingRealm
中的用来获取认证信息的方法,默认是从配置文件中获取认证信息,所以如果想要改变获取认证信息的方法的话,可以自定义一个
Realm
继承
AuthenticatingRealm
抽象方法,实现获取认证信息的方法,声明在shiro中使用自定义的Realm
自定义Realm后续~~~~~~~~~