Shiro初步学习

感谢作者:本文来源 http://www.iocoder.cn/Shiro/xiaoqiyiye/intro/

  • SecurityManager :安全管理,Shiro最核心的组件,Shiro通过SecurityMananger 来管理内部组件的实例,初始化实例。并通过他来提供安全管理的各种服务
  • Authenticator:认证器,认证AuthenticationToken是否有效
  • Authorizer:授权器,处理角色和权限。
  • subject:当前操纵主体,表示当前操作的用户
  • SubjectContext:Subject 上下文数据对象
  • AuthenticationToken:认证token信息,(用户名和密码)
  • ThreadContext:线程上线问对象,负责绑定对象当前线程

在学习和使用Shiro过程中,我们知道SecurityManager接口时Shireo中最合性的接口,我们就沿着这个接口进行分析下面的代码是SecurityManager接口的定义:

    

public interface SecurityManager extends Authenticator, Authorizer, SessionManager {
                         //认证器          //授权器       
    /**
     * 登录
     */
    Subject login(Subject subject, AuthenticationToken authenticationToken) throws AuthenticationException;

    /**
     * 登出
     */         //操作主题当前用户
    void logout(Subject subject);

    /**
     * 创建Subject
     */
    Subject createSubject(SubjectContext context);

}

在SecurityManager 中有三个方法,一个是登陆,等处,创建Object 。通常我们是这么使用的,

  1. 首先创建Subject对象,
  2. 然后通过调用login方法传入认证信息token对登陆进行认证。
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
subject.login(token);

SecurityUtils 分析

在Shiro中提供了一个方便使用的工具类SecurityUtils,SecurityUtils核心功能是获取SecurityManager ,以及获取subject 

 1. 获取SecurityManager

private static 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;
}

 2. 获取Subject

public static Subject getSubject() {
    Subject subject = ThreadContext.getSubject();
    if (subject == null) {
        subject = (new Subject.Builder()).buildSubject();
        ThreadContext.bind(subject);
    }
    return subject;
}

在上边的额代码中重要的是通过Subject.builder 类提供buildSuject()来创建的,在创建Suject的同事还创建了SubjectContext。也就是说,Subject和SubjectContext是一对,下面的代码时Subject.Builder类构造器

public Builder(SecurityManager securityManager) {
    if (securityManager == null) {
        throw new NullPointerException("SecurityManager method argument cannot be null.");
    }
    this.securityManager = securityManager;
    // 创建了SubjectContext实例对象
    this.subjectContext = newSubjectContextInstance();
    if (this.subjectContext == null) {
        throw new IllegalStateException("Subject instance returned from 'newSubjectContextInstance' " +
                "cannot be null.");
    }
    this.subjectContext.setSecurityManager(securityManager);
}

而buildSubject()实际上就是调用SecurityManager接口中的CreateSubject(subjectContext subjectContext)方法

public Subject buildSubject() {
    return this.securityManager.createSubject(this.subjectContext);
}

 

posted @ 2020-06-27 17:59  dousil  阅读(162)  评论(0)    收藏  举报