Shiro内部结构剖析
shiro内部结构图
1、认证流程(也就是登录)
Subject对象传入Security Manager并将内容交给认证器 Authenticator ,但认证器不做任何处理,因为在这时认证器不了解登录信息(数据库,用户名密码,认证规则等),正真进行逻辑判断的地方Realms(从数据库获取数据)从中可以获取很多很多的认证规则。
2、Authrizer 授权器:
判断Subject是否有权限进行相关操作,授权器同理,需要使用Realms进行权限信息判断。
3、SessionManager
如果写过Servlet就应该知道Session的概念, Session呢需要有人去管理它的生命周期,这个组件就是SessionManager ;而Shiro并不仅仅可以用在Web环境,也可以用在如普通的JavaSE环境、EJB等环境; Shiro就抽象了一个自己的Session来管理主体与应用之间交互的数据;
4、SessionDAO :
数据访问对象,用于会话的CRUD ,比如我们想把Session保存到数据库,那么可以实现自己的SessionDAO ,通过如JDBC写到数据库;比如想把Session放到Memcached中,可以实现自己的Memcached
SessionDAO ;另外SessionDAO中可以使用Cache进行缓存,以提高性能;CacheManager :缓存控制器,来管理如用户、角色、权限等的缓存的;因为这些数据基本上很少去改变,放到缓存中后可以提高访问的性能
5、Cryptography :密码模块
Shiro提高了一些常见的加密组件用于如密码加密/解密的。
Shiro基本测试
1、测试用户登录
导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
首先需要在resources中创建一个ini配置文件
shiro-test-1.ini文件内容
#数据格式 用户名=密码
[users]
zs=123
ls=111
测试类:
如果和结果对应上,则返回true;
如果对应不上,则会抛错:org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.jupiter.api.Test;
public class ShiroTest01 {
/**
* 1、初始化一个DefaultSecurityManager实例
* 2、创建一个iniRealm存放ini数据源
* 3、将DefaultSecurityManager绑定到当前运行环境
* 4、从当前运行环境中构造subject
* 5、构造shiro登录的数据(认证数据)
* 6、主体登录
*/
@Test
public void testLogin(){
//1
DefaultSecurityManager manager = new DefaultSecurityManager();
//2
IniRealm iniRealm = new IniRealm("classpath:shiro-test-1.ini");
manager.setRealm(iniRealm);
//3
SecurityUtils.setSecurityManager(manager);
//4
Subject subject = SecurityUtils.getSubject();
//5
String username = "zs";
String password = "123";
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
//6
subject.login(token);
//7、验证用户是否登录成功
System.out.println("用户是否登录成功="+subject.isAuthenticated());
System.out.println(subject.getPrincipal());
}
}
2、测试用户授权
shiro-test-2.ini文件内容
[users]
#用户名=密码,角色名
zs=123,role1,role2
ls=111,role1
[roles]
#角色名称=权限列表
role1=user:save,user:update
role2=user:find
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.subject.Subject;
import org.junit.jupiter.api.Test;
public class ShiroTest02 {
@Test
public void testLogin(){
//以下到空行位置都是基本配置内容
DefaultSecurityManager manager = new DefaultSecurityManager();
IniRealm iniRealm = new IniRealm("classpath:shiro-test-2.ini");
manager.setRealm(iniRealm);
//把DefaultSecurityManager绑定
SecurityUtils.setSecurityManager(manager);
//登录代码实现
Subject subject = SecurityUtils.getSubject();
String username = "ls";
String password = "111";
UsernamePasswordToken token = new UsernamePasswordToken(username,password);
subject.login(token);
//登录成功后,完成授权
//授权:检验用户操作权限,具有的角色
System.out.println(subject.hasRole("role1"));//角色
System.out.println(subject.isPermitted("user:save"));//操作权限
}
}