《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》

摘要: 原创出处 https://my.oschina.net/xiaoqiyiye/blog/1619214 「xiaoqiyiye」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

本文在于分析Shiro源码,对于新学习的朋友可以参考
[开涛博客](http://jinnianshilongnian.iteye.com/blog/2018398)进行学习。

Subject接口

在Shiro中Subject表示系统进行交互的用户或某一个第三方服务,所有Subject实例都被绑定到(且这是必须的)一个SecurityManager上。Subject接口提供了很多方法,主要包括进行认证的登录登出方法、进行授权判断的方法和Session访问的方法。在Shiro中获取当前运行的Subject要使用SecurityUtils.getSubject()方法来获取一个Subject实例。

下面将Subject接口方法进行分类:

  1. 和认证的相关的方法

// 返回可以鉴定Subject唯一性的身份信息,例如:用户名、用户ID等等
Object getPrincipal();

// 以PrincipalCollection形式返回身份信息
PrincipalCollection getPrincipals();

// 是否已经被认证通过
boolean isAuthenticated();

// 登录认证
void login(AuthenticationToken token) throws AuthenticationException;

// 认证登出
void logout();

  1. 和授权相关的方法

// 是否有指定的权限
boolean isPermitted(String permission);

// 是否有指定的权限
boolean isPermitted(Permission permission);

// 是否有指定的权限
boolean[] isPermitted(String... permissions);

// 是否有指定的权限
boolean[] isPermitted(List<Permission> permissions);

// 是否有所有指定的权限
boolean isPermittedAll(String... permissions);

// 是否有所有指定的权限
boolean isPermittedAll(Collection<Permission> permissions);

// 检测是否有权限,如果没有将抛出异常
void checkPermission(String permission) throws AuthorizationException;

// 检测是否有权限,如果没有将抛出异常
void checkPermission(Permission permission) throws AuthorizationException;

// 检测是否有权限,如果没有将抛出异常
void checkPermissions(String... permissions) throws AuthorizationException;

// 检测是否有权限,如果没有将抛出异常
void checkPermissions(Collection<Permission> permissions) throws AuthorizationException;

// 是否有指定角色
boolean hasRole(String roleIdentifier);

// 是否有指定角色
boolean[] hasRoles(List<String> roleIdentifiers);

// 是否有所有指定角色
boolean hasAllRoles(Collection<String> roleIdentifiers);

// 检测是否有指定角色,如果没有将抛出异常
void checkRole(String roleIdentifier) throws AuthorizationException;

// 检测是否有所有指定角色,如果没有将抛出异常
void checkRoles(Collection<String> roleIdentifiers) throws AuthorizationException;

// 检测是否有所有指定角色,如果没有将抛出异常
void checkRoles(String... roleIdentifiers) throws AuthorizationException;

  1. 和Session相关方法

// 获取关联的Session,如果没有将会创建新Session
Session getSession();

// 获取关联的Session,如果Session不存在并且create=false,将不会创建新Session
Session getSession(boolean create);

  1. runAs相关的方法

void runAs(PrincipalCollection principals) throws NullPointerException, IllegalStateException;

boolean isRunAs();

PrincipalCollection getPreviousPrincipals();

PrincipalCollection releaseRunAs();

在Subject接口中还提供了一个静态内部类Builder,这个类辅助创建Subject实例。在Builder中需要引用SubjectContext和SecurityManager,SubjectContext负责收集Subject的上下文信息,SecurityManger才是真实创建Subject的对象,通过createSubject(SubjectContext subjectContext)方法来创建,SubjectContext和SessionContext类是,我们可以将它看作一个Map对象。创建Subject已经在Shiro源码分析(1) - Shiro开篇中分析过了,这里不再赘述。

Shiro登录

Shiro源码分析(1) - Shiro开篇中我们已经了解了Subject是如何创建的,这里我们将分析Shiro是如何处理登