Shiro内部结构可看这些文章:
https://blog.csdn.net/Pruett/article/details/81537411、
https://my.oschina.net/liuyuantao/blog/804413、
案例demo: https://www.cnblogs.com/nfcm/p/9870821.html。
简化Demo
Factory<SecurityManager> factory =
new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager securityManager =
factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession();
if (!subject.isAuthenticated()){
UsernamePasswordToken token =
new UsernamePasswordToken("test","123456");
token.setRememberMe(true);
subject.login(token);
logger.info("用户[ " + subject.getPrincipal() + " ]登陆成功");
if (subject.hasRole("admin")){
logger.info("你有 Admin Role");
}
1、SecurityManager
demo 案例获取到的是DefaultSecurityManager。
2、Subject
通过Subject subject = SecurityUtils.getSubject();获取
获取的是 DelegatingSubject,通过Demo代码也可以知道Subject有SecurityManager对象。
3、Session
Session session = subject.getSession();
通过 debug最终到达还是通过securityManager
Session session = this.securityManager.start(sessionContext);
4、SessionManager
public Session start(SessionContext context) throws AuthorizationException {
return this.sessionManager.start(context);
}
由此可知:securityManager有sessionManager对象。sessionManager是 DefaultSessionManager
5、SessionValidationScheduler
再进一步debug
protected Session createSession(SessionContext context) throws AuthorizationException {
this.enableSessionValidationIfNecessary();
return this.doCreateSession(context);
}
this.enableSessionValidationIfNecessary()是进行定时任务,判断Session的时效性,
sessionManager 有SessionValidationScheduler对象
定时任务执行:
public void run() {
if(log.isDebugEnabled()) {
log.debug("Executing session validation...");
}
long startTime = System.currentTimeMillis();
this.sessionManager.validateSessions();
long stopTime = System.currentTimeMillis();
if(log.isDebugEnabled()) {
log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
}
}
sessionManager校验:
protected void validate(Session session, SessionKey key) throws InvalidSessionException {
try {
this.doValidate(session);
} catch (ExpiredSessionException var4) {
this.onExpiration(session, var4, key);
throw var4;
} catch (InvalidSessionException var5) {
this.onInvalidation(session, var5, key);
throw var5;
}
}
处理过程: this.onExpiration(session, var4, key);
try {
this.onExpiration(s);
this.notifyExpiration(s);
} finally {
this.afterExpired(s);
}
this.afterExpired(s);删除过期session
protected void afterExpired(Session session) {
if(this.isDeleteInvalidSessions()) {
this.delete(session);
}
}
6、SessionFactory
启动SessionValidationScheduler后。进行Session的创建:
this.getSessionFactory().createSession(context); sessionFactory 为SimpleSessionFactory。
public Session createSession(SessionContext initData) {
if(initData != null) {
String host = initData.getHost();
if(host != null) {
return new SimpleSession(host);
}
}
return new SimpleSession();
}
7、SessionDao
创建空的SimpleSession后进行赋值。SessionManager含有对象SessionDao
protected void create(Session session) {
if(log.isDebugEnabled()) {
log.debug("Creating new EIS record for new session instance [" + session + "]");
}
this.sessionDAO.create(session);
}
8、SessionIdGenerator
生成Session 的id并赋值给session。SessionDao 含有SessionIdGenerator
protected Serializable doCreate(Session session) {
Serializable sessionId = this.generateSessionId(session);
this.assignSessionId(session, sessionId);
return sessionId;
}
9、authenticator 认证器
subject.login(token);进行登录 。可知SecurityManager 含有authenticator -ModularRealmAuthenticator
public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
return this.authenticator.authenticate(token);
}
10、Real
保存授权信息。authenticator 与authorizer 都有,用去存储角色、用户与权限。
11、authorizer 授权器 ModularRealmAuthorizer SecurityManager 含有authorizer
public boolean hasRole(PrincipalCollection principals, String roleIdentifier) {
return this.authorizer.hasRole(principals, roleIdentifier);
}
PS:现在画时序图不太熟练,之后有时间再补上