鲁春利的工作笔记,好记性不如烂笔头
1、Shiro配置文件(first-shiro.ini)
[users]
lucl=123
wang=123
2、单元测试类
@Test
public void testLoginWithNoGivenRealm () {
// 1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro/first-shiro.ini");
// 2、得到SecurityManager实例并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
// org.apache.shiro.mgt.DefaultSecurityManager
logger.info("security manager is " + securityManager + ".");
SecurityUtils.setSecurityManager(securityManager);
// 3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("lucl", "123");
try{
// 4、登录,即身份验证
subject.login(token);
} catch (AuthenticationException e) {
// 5、身份验证失败
logger.info("用户身份验证失败");
e.printStackTrace();
}
Assert.assertEquals(true, subject.isAuthenticated()); //断言用户已经登录
if (subject.isAuthenticated()) {
logger.info("用户登录成功。");
} else {
logger.info("用户登录失败。");
}
// 6、退出
subject.logout();
}
3、过程分析
3.1、获取SecurityManager工厂
new IniSecurityManagerFactory("classpath:shiro/first-shiro.ini");
package org.apache.shiro.config;
/**
* A Factory that creates SecurityManager instances based on Ini configuration.
*
* @since 1.0
*/
public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager> {
public static final String MAIN_SECTION_NAME = "main";
public static final String SECURITY_MANAGER_NAME = "securityManager";
public static final String INI_REALM_NAME = "iniRealm";
private ReflectionBuilder builder;
// 略
public IniSecurityManagerFactory(Ini config) {
setIni(config);
}
// new IniSecurityManagerFactory(ini文件路径),然后会调用IniSecurityManagerFactory(Ini config)
public IniSecurityManagerFactory(String iniResourcePath) {
this(Ini.fromResourcePath(iniResourcePath));
}
// 略
}
setIni(config);
调用IniFactorySupport类的setIni方法
package org.apache.shiro.config;
/**
* Base support class for Factory implementations that generate their instance(s) based on Ini configuration.
*
* @since 1.0
*/
public abstract class IniFactorySupport<T> extends AbstractFactory<T> {
public static final String DEFAULT_INI_RESOURCE_PATH = "classpath:shiro.ini";
private static transient final Logger log = LoggerFactory.getLogger(IniFactorySupport.class);
private Ini ini;
protected IniFactorySupport() {
}
protected IniFactorySupport(Ini ini) {
this.ini = ini;
}
public Ini getIni() {
return ini;
}
public void setIni(Ini ini) {
this.ini = ini;
}
}
3.2、得到SecurityManager实例并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
factory.getInstance();调用AbstractFactory的getInstance()方法
package org.apache.shiro.util;
/**
* TODO - Class JavaDoc
*
* @since 1.0
*/
public abstract class AbstractFactory<T> implements Factory<T> {
private boolean singleton;
private T singletonInstance;
// 无参构造方法,默认会被容器加载,因此singleton标识默认为true
public AbstractFactory() {
this.singleton = true;
}
public boolean isSingleton() {
return singleton;
}
public void setSingleton(boolean singleton) {
this.singleton = singleton;
}
public T getInstance() {
T instance;
if (isSingleton()) { // true
if (this.singletonInstance == null) { // 调用createInstance方法
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;
}
// 方法为抽象方法,因此会调用子类(IniFactorySupport)的实现
protected abstract T createInstance();
}
调用子类(IniFactorySupport)的createInstance()
package org.apache.shiro.config;
public abstract class IniFactorySupport<T> extends AbstractFactory<T> {
/**
* Creates a new object instance by using a configured INI source.
* 1、获取ini指定的配置文件(resolveIni会调用getIni,读取之前setIni时的值);
* 2、若ini为空通过createDefaultInstance()方法创建默认的实例(default instance);否则基于ini创建实例(createInstance(ini))
*/
public T createInstance() {
Ini ini = resolveIni();
T instance;
if (CollectionUtils.isEmpty(ini)) {
log.debug("No populated Ini available. Creating a default instance.");
instance = createDefaultInstance();
if (instance == null) {
// 异常信息略
throw new IllegalStateException(msg);
}
} else {
log.debug("Creating instance from Ini [" + ini + "]");
instance = createInstance(ini);
if (instance == null) {
// 异常信息略
throw new IllegalStateException(msg);
}
}
return instance;
}
// 为抽象方法,需要调用其实现类的createInstance(Ini ini)方法
protected abstract T createInstance(Ini ini);
// 为抽象方法,需要调用其实现类的createDefaultInstance()方法
protected abstract T createDefaultInstance();
}
IniSecurityManagerFactory类的createDefaultInstance()
public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager> {
protected SecurityManager createDefaultInstance() {
return new DefaultSecurityManager();
}
}
IniSecurityManagerFactory类的createInstance(Ini ini)
public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager> {
protected SecurityManager createInstance(Ini ini) {
if (CollectionUtils.isEmpty(ini)) {
throw new NullPointerException("Ini argument cannot be null or empty.");
}
// 最核心的是createSecurityManager方法
SecurityManager securityManager = createSecurityManager(ini);
if (securityManager == null) {
String msg = SecurityManager.class + " instance cannot be null.";
throw new ConfigurationException(msg);
}
return securityManager;
}
}
IniSecurityManagerFactory类的createSecurityManager(Ini ini)方法
public class IniSecurityManagerFactory extends IniFactorySupport<SecurityManager> {
private SecurityManager createSecurityManager(Ini ini) {
Ini.Section mainSection = ini.getSection(MAIN_SECTION_NAME); //"main"
if (CollectionUtils.isEmpty(mainSection)) {
//try the default:
mainSection = ini.getSection(Ini.DEFAULT_SECTION_NAME);
}
return createSecurityManager(ini, mainSection);
}
// 中间代码略
@SuppressWarnings({"unchecked"})
private SecurityManager createSecurityManager(Ini ini, Ini.Section mainSection) {
// 实际上获取到SecurityManager的地方是在createDefaults
Map<String, ?> defaults = createDefaults(ini, mainSection);
// buildInstances实际上是ReflectionBuilder对defaults进行了处理
Map<String, ?> objects = buildInstances(mainSection, defaults);
// getSecurityManagerBean=>builder.getBean(SECURITY_MANAGER_NAME, SecurityManager.class);
SecurityManager securityManager = getSecurityManagerBean();
boolean autoApplyRealms = isAutoApplyRealms(securityManager);
if (autoApplyRealms) {
//realms and realm factory might have been created - pull them out first so we can
//initialize the securityManager:
Collection<Realm> realms = getRealms(objects);
//set them on the SecurityManager
if (!CollectionUtils.isEmpty(realms)) {
applyRealmsToSecurityManager(realms, securityManager);
}
}
return securityManager;
}
// 转了一圈还是调用createDefaultInstance()
protected Map<String, ?> createDefaults(Ini ini, Ini.Section mainSection) {
Map<String, Object> defaults = new LinkedHashMap<String, Object>();
SecurityManager securityManager = createDefaultInstance();
defaults.put(SECURITY_MANAGER_NAME, securityManager);
// public static final String INI_REALM_NAME = "iniRealm";
if (shouldImplicitlyCreateRealm(ini)) {
Realm realm = createRealm(ini); // IniRealm realm = new IniRealm();
if (realm != null) {
defaults.put(INI_REALM_NAME, realm);
}
}
return defaults;
}
}
转载于:https://blog.51cto.com/luchunli/1828405