SecurityUtils是一个抽象的工具类,提供了 SecurityManager 实例的保存和获取的方法,以及创建Subject的方法。
一:SecurityUtils中的方法
SecurityUtils提供了 getSecurityManager()和setSecurityManager外,还有个特别的方法 getSubject(),这是获取subject的最有效的途径。
下面是 SecurityUtils 提供的三个方法:
package org.apache.shiro; import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.subject.Subject;import org.apache.shiro.util.ThreadContext; public abstract class SecurityUtils { private static SecurityManager securityManager; public static Subject getSubject() { Subject subject = ThreadContext.getSubject(); if (subject == null) { subject = (new Subject.Builder()).buildSubject(); ThreadContext.bind(subject); } return subject; } public static void setSecurityManager(SecurityManager securityManager) { SecurityUtils.securityManager = securityManager; } public static SecurityManager getSecurityManager() throws UnavailableSecurityManagerException { SecurityManager securityManager = ThreadContext.getSecurityManager(); if (securityManager == null) { securityManager = SecurityUtils.securityManager; } if (securityManager == null) { String msg = "No SecurityManager accessible to the calling code, either bound to the " + ThreadContext.class.getName() + " or as a vm static singleton. This is an invalid application " + "configuration."; throw new UnavailableSecurityManagerException(msg); } return securityManager; }}
二:最终subject创建的代码
DefaultSecurityManager 实例化的时候,生成了 SubjectFactory子类 DefaultSubjectFactory 实例的属性。
DefaultSecurityManager的createSubject()方法 调用 DefaultSubjectFactory 的 createSubject()方法最终完成了subject 的创建: 下面是 DefaultSubjectFactory 中createSubject()方法的代码:
package org.apache.shiro.mgt; import org.apache.shiro.session.Session;import org.apache.shiro.subject.PrincipalCollection;import org.apache.shiro.subject.Subject;import org.apache.shiro.subject.SubjectContext;import org.apache.shiro.subject.support.DelegatingSubject; /** * Default {@link SubjectFactory SubjectFactory} implementation that creates {@link org.apache.shiro.subject.support.DelegatingSubject DelegatingSubject} * instances. * * @since 1.0 */public class DefaultSubjectFactory implements SubjectFactory { public DefaultSubjectFactory() { } public Subject createSubject(SubjectContext context) { SecurityManager securityManager = context.resolveSecurityManager(); Session session = context.resolveSession(); boolean sessionCreationEnabled = context.isSessionCreationEnabled(); PrincipalCollection principals = context.resolvePrincipals(); boolean authenticated = context.resolveAuthenticated(); String host = context.resolveHost(); return new DelegatingSubject(principals, authenticated, host, session, sessionCreationEnabled, securityManager); } /** * @deprecated since 1.2 - override {@link #createSubject(org.apache.shiro.subject.SubjectContext)} directly if you * need to instantiate a custom {@link Subject} class. */ @Deprecated protected Subject newSubjectInstance(PrincipalCollection principals, boolean authenticated, String host, Session session, SecurityManager securityManager) { return new DelegatingSubject(principals, authenticated, host, session, true, securityManager); } }
可见,subject的最终实例是 DelegatingSubject的实例,并且包含host,authenticated,principals,securityManager等丰富的信息。