shiro框架源码解析与改造(六)---Subject创建

在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);
        }

    }

猜你喜欢

转载自blog.csdn.net/ljz2016/article/details/81216382
今日推荐