在AbstractShiroFilter中创建subject
protected WebSubject createSubject(ServletRequest request, ServletResponse response) {
return (new WebSubject.Builder(this.getSecurityManager(), request, response)).buildWebSubject();
}
WebSubject调用了父类的buildSubject方法
public WebSubject buildWebSubject() {
Subject subject = super.buildSubject();
if(!(subject instanceof WebSubject)) {
String msg = "Subject implementation returned from the SecurityManager was not a " + WebSubject.class.getName() + " implementation. Please ensure a Web-enabled SecurityManager has been configured and made available to this builder.";
throw new IllegalStateException(msg);
} else {
return (WebSubject)subject;
}
}
在父类的buildSubject中,委托securityManager来创建subject:
public Subject buildSubject() {
return this.securityManager.createSubject(this.subjectContext);
}
在DefaultSecurityManager中
@Override
public Subject createSubject(SubjectContext context) {
context = this.ensureSecurityManager(context);
context = this.resolveSession(context);
context = this.resolvePrincipals(context);
Subject subject = this.doCreateSubject(context);
this.save(subject);
return subject;
}
protected Subject doCreateSubject(SubjectContext context) {
return this.getSubjectFactory().createSubject(context);
}
由subjectFactory来创建subject,返回WebDelegatingSubject:
public class DefaultWebSubjectFactory extends DefaultSubjectFactory implements SubjectFactory {
public Subject createSubject(SubjectContext context) {
if(!(context instanceof WebSubjectContext)) {
return super.createSubject(context);
} else {
WebSubjectContext wsc = (WebSubjectContext)context;
SecurityManager securityManager = wsc.resolveSecurityManager();
Session session = wsc.resolveSession();
boolean sessionEnabled = wsc.isSessionCreationEnabled();
PrincipalCollection principals = wsc.resolvePrincipals();
boolean authenticated = wsc.resolveAuthenticated();
String host = wsc.resolveHost();
ServletRequest request = wsc.resolveServletRequest();
ServletResponse response = wsc.resolveServletResponse();
return new WebDelegatingSubject(principals, authenticated, host, session, sessionEnabled, request, response, securityManager);
}
}
}
回调方法
@Override
public <V> V execute(Callable<V> callable) throws ExecutionException {
Callable<V> assocaited=this.associateWith(callable);
try {
return assocaited.call();
} catch (Exception e) {
throw new com.cmst.simpleshiro.subject.ExecutionException(e);
}
}
@Override
public <V> Callable<V> associateWith(Callable<V> callable) {
return new SubjectCallable(this,callable);
}
@Override
public V call() throws Exception {
V result;
try {
this.threadState.bind();
result = this.doCall(this.callable);
} finally {
this.threadState.restore();
}
return result;
}
在执行callable方法前,会把subject保存到当前线程中。
public void bind() {
SecurityManager securityManager = this.securityManager;
if (securityManager == null) {
securityManager = ThreadContext.getSecurityManager();
}
this.originalResources = ThreadContext.getResources();
ThreadContext.remove();
ThreadContext.bind(this.subject);//把subject保存到当前线程中。
if (securityManager != null) {
ThreadContext.bind(securityManager);
}
}