第一章
Apache 初次接触
Apache Shiro 是一个Java安全框架,提供了授权,认证,授权加密和会话管理等功能.
- 认证(AuthentiCation) - 身份识别和验证
- 授权(AuthoriZation) - 访问控制
- 密码加密
- 会话管理
首先看下简单实例
依赖如下:
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
shiro.ini
[users]
chen=123
he=123
测试代码
public void testLoginLogout(){
//1.获取Security工厂,此处处理Ini配置文件初始化SecurityManager
Factory<SecurityManager> facoty = new IniSecurityManagerFactory("classpath:shiro-capter2.ini");
//2.得到Security实例,并绑定到SecurityUtils
SecurityManager securityManager = facoty.getInstance();
SecurityUtils.setSecurityManager(securityManager);
//3.得到Subject及创建用户名/密码身份验证Token
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("chen","123");
try {
//4.登录,即身份验证
subject.login(token);
}catch (AuthenticationException e){
e.printStackTrace();
}
//断言用户已经登录
Assert.assertEquals(true,subject.isAuthenticated());
//6.退出
subject.logout();
//7.断言用户已经退出
Assert.assertEquals(false,subject.isAuthenticated());
}
分析:
IniSecurityManagerFactory继承关系如图,由上至下分析
1.Factory
Factory是一个接口,提供工厂模式的支持,它仅有一个方法
T getInstance();
2.AbstractFactory
- AbstractFactory 实现了 Factory接口,看下它的变量
private boolean singleton; //默认是单例 用来控制getInstance方法是创建一个新的Instance还是使用单例模式
private T singletonInstance; //getInstance的返回类型主要方法如下:
- 主要方法如下
public T getInstance() {
T instance;
if (isSingleton()) {//单例模式,只创建一个对象
if (this.singletonInstance == null) {
this.singletonInstance = createInstance();
}
instance = this.singletonInstance;
} else {
instance = createInstance();//非单例模式,每次都新创建一个对象
}
if (instance == null) {
String msg = "Factory 'createInstance' implementation returned a null object.";
throw new IllegalStateException(msg);
}
return instance;
}
protected abstract T createInstance();
3.IniFactorySupport
IniFactorySupport继承自AbstoryFactory,并实现了createInstance()方法;
看下createInstance()
public T createInstance() {
Ini ini = resolveIni();//ini对象是否存在
T instance;
if (CollectionUtils.isEmpty(ini)) {//不存在ini对象,通过在默认classpath:shiro.ini创建ini对象
log.debug("No populated Ini available. Creating a default instance.");
instance = createDefaultInstance();
if (instance == null) {
String msg = getClass().getName() + " implementation did not return a default instance in " +
"the event of a null/empty Ini configuration. This is required to support the " +
"Factory interface. Please check your implementation.";
throw new IllegalStateException(msg);
}
} else { //ini存在,则创建实例
log.debug("Creating instance from Ini [" + ini + "]");
instance = createInstance(ini);
if (instance == null) {
String msg = getClass().getName() + " implementation did not return a constructed instance from " +
"the createInstance(Ini) method implementation.";
throw new IllegalStateException(msg);
}
}
return instance;
}
主要成员变量:
public static final String DEFAULT_INI_RESOURCE_PATH = "classpath:shiro.ini"; //默认ini配置文件路径
private Ini ini;//init配置文件解析
4.IniSecurityManagerFactory
它继承自IniFactorySupport,给泛型限定了类型<SecurityManager>
public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager> {...}
实现了createInstance(Ini ini);方法
protected SecurityManager createInstance(Ini ini) {
if (CollectionUtils.isEmpty(ini)) {
throw new NullPointerException("Ini argument cannot be null or empty.");
}
SecurityManager securityManager = createSecurityManager(ini);
if (securityManager == null) {
String msg = SecurityManager.class + " instance cannot be null.";
throw new ConfigurationException(msg);
}
return securityManager;
}
5.SecurityManager
它是Shiro框架的核心,典型的Facade模式,Shiro通过SecurityManager来管理内部组件实例,并通过它来提供安全管理的各种服务。
继承关系如下
三个接口分别为认证管理(Authenticator),授权管理(Authorizer),会话管理(SessionManager)
SecurityManager除了提供父接口的方法外,还提供了三个其它
Subject login(Subject subject, AuthenticationToken authenticationToken) throws AuthenticationExceptio;
void logout(Subject subject);
Subject createSubject(SubjectContext context);
6.SecurityUtils
SecurityUtils是一个抽象的工具类,提供了SecurityManager实例的保存和获取的方法,以及创建Subject.
7.Subject
即“当前操作用户”。但是,在Shiro中,Subject这一概念并不仅仅指人,也可以是第三方进程、后台帐户(Daemon Account)或其他类似事物。它仅仅意味着“当前跟软件交互的东西”。但考虑到大多数目的和用途,你可以把它认为是Shiro的“用户”概念。