shiro安全控制目录
门面模式的本质就是化零为整:引入一个中介类,把各个分散的功能组合成一个整体,只对外暴露一个统一的接口。门面模式实现了SecurityManager的功能模块化,如图1所示。
图1-shiro和门面模式.png
用户只是简单的调用Subject API,而无需关心SecurityMananger中各个功能之间的相互调用。
1. subject类
用户在shiro中用subject表示,使用的默认类是org.apache.shiro.web.subject.support.WebDelegatingSubject
,包含的参数,如图2所示。
图2-subject的参数.png
subject的生命周期:
- 每一次访问都会创建一个新的subject对象。
- 将创建的subject对象绑定到ThreadContext上,之后通过SecurityUtils便可以在程序的任何地方获取到Subject对象。
- 每一次创建完成subject,都会通过SubjectDAO将subject属性存放到session中去,但是只存放principal(身份)和authenticated(是否校验成功)。
2. subjectDAO
subject在创建完成之后,都会通过org.apache.shiro.mgt.DefaultSubjectDAO
,将subject的属性保存到session中去。但是决定是否进行保存是由sessionStorageEvaluator
参数进行控制的。
使用session来持久化保存Subject的principal(身份)和authenticated(是否校验成功)。在Session中保存Subject信息后,通过cookie上送的sessionId,shiro便可以根据session来重建Subject实例。
用户每次请求,均使用session重建subject对象,那么我们可以修改session中的身份信息,以实现用户非重新登录,便可获取到最新的身份信息principal。
源码参考:org.apache.shiro.mgt.DefaultSubjectDAO#mergePrincipals
但是在无状态认证中,请求每次携带token,每次都要经过身份认证。通常就不需要session来存储此状态。便可以禁止存储,如代码1所示。
代码1:禁止session存储subject信息。
@Bean
public DefaultSubjectDAO defaultSubjectDAO() {
return new DefaultSubjectDAO() {
@Override
protected boolean isSessionStorageEnabled(Subject subject) {
return false;
}
};
}