2.详解SecurityManager(shiro权限管理门面)
来源:互联网 发布:土木工程领域大数据 编辑:程序博客网 时间:2024/05/22 00:27
SecurityManager 接口主要作用
为什么要先说SecurityManager呢?因为我觉得他是shiro的主要入口,几乎所有相关的权限操作,都由他代理了。
1.可以说是所有配置的入口,简化配置,方便使用。
2.一个接口就可以实现,验证的操作(登录、退出)、授权(授权访问指定资源、角色)、Session管理,相当于这些操作的门面(门面模式,也叫外观模式)。
从上图我们可以看出SecurityManager各个子类的作用及子类的依赖组件的接口。下面我们底层子类往上推,分别详解各个子类的作用
1. CachingSecurityManager
//该抽象类实现类CacheManagerAware 接口,主要提供缓存支持,管理缓存操作public abstract class CachingSecurityManager implements SecurityManager, Destroyable, CacheManagerAware { //缓存接口的实现类,实现可以是ehcache,java的HashMap版的cacheManager,redis private CacheManager cacheManager; //通过该接口可以获取cacheManager,然后使用它来做一些你所需的操作,如进行一些自定义的缓存管理 public CacheManager getCacheManager() { return cacheManager; } public void setCacheManager(CacheManager cacheManager) { this.cacheManager = cacheManager; //在设置cacheManager后,执行一些后续操作。该后续操作主要是:设置cacheManagr到Realm和SessionManager等相关依cacheManagr的类 afterCacheManagerSet(); } //Template 方法,让子类重写实现业务逻辑 protected void afterCacheManagerSet() { } //销毁SecurityManager时,销毁该缓存实例 public void destroy() { LifecycleUtils.destroy(getCacheManager()); this.cacheManager = null; }}
2.RealmSecurityManager
//该抽象类主要是管理Realm(可以理解为数据处理组件,比如Realm根据用户名查找底层数据库,然后取出来和你输入的用户密码进行批评,验证是否equals来验证是否登陆成功,还有授权数据等)public abstract class RealmSecurityManager extends CachingSecurityManager { //至少需要一个Realm,可以是多个。相当于多个数据处理中心,比如mysql数据库,redis数据库 private Collection<Realm> realms; public void setRealm(Realm realm) { if (realm == null) { throw new IllegalArgumentException("Realm argument cannot be null"); } Collection<Realm> realms = new ArrayList<Realm>(1); realms.add(realm); setRealms(realms); } public void setRealms(Collection<Realm> realms) { if (realms == null) { throw new IllegalArgumentException("Realms collection argument cannot be null."); } if (realms.isEmpty()) { throw new IllegalArgumentException("Realms collection argument cannot be empty."); } this.realms = realms; //模板方法,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中 afterRealmsSet(); } protected void afterRealmsSet() { applyCacheManagerToRealms(); } //获取realm,根据你是否有需求来决定使用。可能应用场景:从Realm中获取用户的授权、验证的缓存信息 public Collection<Realm> getRealms() { return realms; } //设置cacheManager到Realm中,因为Realm是数据处理组件,当它从数据库中加载数据且得到正确的验证后,可以缓存到cacheManager,来提供性能。在shiro里,AuthorizationInfo(授权数据)和AuthenticationInfo(用户基本账户密码)都被缓存到cacheManager在验证成功后 protected void applyCacheManagerToRealms() { CacheManager cacheManager = getCacheManager(); Collection<Realm> realms = getRealms(); if (cacheManager != null && realms != null && !realms.isEmpty()) { for (Realm realm : realms) { if (realm instanceof CacheManagerAware) { ((CacheManagerAware) realm).setCacheManager(cacheManager); } } } } protected void afterCacheManagerSet() { applyCacheManagerToRealms(); } //销毁realms public void destroy() { LifecycleUtils.destroy(getRealms()); this.realms = null; super.destroy(); }}
3.AuthenticatingSecurityManager
//实现接口Authenticator,处理用户登陆验证的 SecurityManager 的 抽象实现,仅仅代理Authenticator.public abstract class AuthenticatingSecurityManager extends RealmSecurityManager { //依赖authenticator验证器,真正的登陆验证都在这里面处理 private Authenticator authenticator; public AuthenticatingSecurityManager() { super(); //默认的Authenticator,在大多数情况下,该默认实例足够用了 this.authenticator = new ModularRealmAuthenticator(); } public Authenticator getAuthenticator() { return authenticator; } //覆盖默认的ModularRealmAuthenticator public void setAuthenticator(Authenticator authenticator) throws IllegalArgumentException { if (authenticator == null) { String msg = "Authenticator argument cannot be null."; throw new IllegalArgumentException(msg); } this.authenticator = authenticator; } //重写父类模板方法 protected void afterRealmsSet() { super.afterRealmsSet(); if (this.authenticator instanceof ModularRealmAuthenticator) { ((ModularRealmAuthenticator) this.authenticator).setRealms(getRealms()); } } //该类的核心,调用底层的authenticator进行用户输入的账户密码验证 //token 是用户输入的账户密码 public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException { return this.authenticator.authenticate(token); } //销毁Authenticator public void destroy() { LifecycleUtils.destroy(getAuthenticator()); this.authenticator = null; super.destroy(); }}
4.AuthorizingSecurityManager
//AuthorizingSecurityManager是实现了Authorizer接口的抽象类,该类主要代理Authorizer进行授权。public abstract class AuthorizingSecurityManager extends AuthenticatingSecurityManager { //真正的授权器 private Authorizer authorizer; public AuthorizingSecurityManager() { super(); //默认的Authorizer,该默认实例支持大部分使用场景 this.authorizer = new ModularRealmAuthorizer(); } public Authorizer getAuthorizer() { return authorizer; } //覆盖默认的Authorizer public void setAuthorizer(Authorizer authorizer) { if (authorizer == null) { String msg = "Authorizer argument cannot be null."; throw new IllegalArgumentException(msg); } this.authorizer = authorizer; } //重写父类的afterRealmsSet(),首先调用父类的afterRealmsSet(),然后在设置realms到授权器,如果实现是ModularRealmAuthorizer。也就是说如果你覆盖了默认的 ModularRealmAuthorizer,那么你要对这个方法进行处理。 protected void afterRealmsSet() { super.afterRealmsSet(); if (this.authorizer instanceof ModularRealmAuthorizer) { ((ModularRealmAuthorizer) this.authorizer).setRealms(getRealms()); } } public void destroy() { LifecycleUtils.destroy(getAuthorizer()); this.authorizer = null; super.destroy(); } /** 以下都是调用底层的authorizer来进行授权处理。所有的用户是否能授权其实就是调用以下方法。后面详讲authorizer,会讲解每个方法的意思,大家可以随便看看有个影像就可以了。 总的来说就两类:一类是返回true false来说明是否授权成功,一个抛异常来说明是否授权成功 **/ public boolean isPermitted(PrincipalCollection principals, String permissionString) { return this.authorizer.isPermitted(principals, permissionString); } public boolean isPermitted(PrincipalCollection principals, Permission permission) { return this.authorizer.isPermitted(principals, permission); } public boolean[] isPermitted(PrincipalCollection principals, String... permissions) { return this.authorizer.isPermitted(principals, permissions); } public boolean[] isPermitted(PrincipalCollection principals, List<Permission> permissions) { return this.authorizer.isPermitted(principals, permissions); } public boolean isPermittedAll(PrincipalCollection principals, String... permissions) { return this.authorizer.isPermittedAll(principals, permissions); } public boolean isPermittedAll(PrincipalCollection principals, Collection<Permission> permissions) { return this.authorizer.isPermittedAll(principals, permissions); } public void checkPermission(PrincipalCollection principals, String permission) throws AuthorizationException { this.authorizer.checkPermission(principals, permission); } public void checkPermission(PrincipalCollection principals, Permission permission) throws AuthorizationException { this.authorizer.checkPermission(principals, permission); } public void checkPermissions(PrincipalCollection principals, String... permissions) throws AuthorizationException { this.authorizer.checkPermissions(principals, permissions); } public void checkPermissions(PrincipalCollection principals, Collection<Permission> permissions) throws AuthorizationException { this.authorizer.checkPermissions(principals, permissions); } public boolean hasRole(PrincipalCollection principals, String roleIdentifier) { return this.authorizer.hasRole(principals, roleIdentifier); } public boolean[] hasRoles(PrincipalCollection principals, List<String> roleIdentifiers) { return this.authorizer.hasRoles(principals, roleIdentifiers); } public boolean hasAllRoles(PrincipalCollection principals, Collection<String> roleIdentifiers) { return this.authorizer.hasAllRoles(principals, roleIdentifiers); } public void checkRole(PrincipalCollection principals, String role) throws AuthorizationException { this.authorizer.checkRole(principals, role); } public void checkRoles(PrincipalCollection principals, Collection<String> roles) throws AuthorizationException { this.authorizer.checkRoles(principals, roles); } public void checkRoles(PrincipalCollection principals, String... roles) throws AuthorizationException { this.authorizer.checkRoles(principals, roles); } }
5.SessionsSecurityManager
//SessionsSecurityManager实现类SessionManager的方法。代理了SessionManager来处理相关的session操作。public abstract class SessionsSecurityManager extends AuthorizingSecurityManager { //Session管理 private SessionManager sessionManager; public SessionsSecurityManager() { super(); //默认的SessionManager的实现类 this.sessionManager = new DefaultSessionManager(); //顾名思义,设置CacheManager到sessionManager applyCacheManagerToSessionManager(); } public void setSessionManager(SessionManager sessionManager) { this.sessionManager = sessionManager; afterSessionManagerSet(); } //在sessionManager被设置后调用,该类只调用 applyCacheManagerToSessionManager(),大家可以琢磨下这样写的好处,子类可以重写增强等 protected void afterSessionManagerSet() { applyCacheManagerToSessionManager(); } //获取sessionManager,根据你的需求。除了下面的方法,可能使用场景:获取所有在线session public SessionManager getSessionManager() { return this.sessionManager; } //增强父类的afterCacheManagerSet(),满足本类需求 protected void afterCacheManagerSet() { super.afterCacheManagerSet(); applyCacheManagerToSessionManager(); } //如果sessionManager实现了CacheManagerAware,则设置cacheManager protected void applyCacheManagerToSessionManager() { if (this.sessionManager instanceof CacheManagerAware) { ((CacheManagerAware) this.sessionManager).setCacheManager(getCacheManager()); } } //调用sessionManager根据上下文context(存储session的相关创建信息,大家可以去了解下上下文)创建个session public Session start(SessionContext context) throws AuthorizationException { return this.sessionManager.start(context); } //根据sessionID来获取session,每次生成session后会生成个sessionID返回给浏览器,浏览器用sessionID来和sessionManager进行交互 public Session getSession(SessionKey key) throws SessionException { return this.sessionManager.getSession(key); } //销毁sessionManager public void destroy() { LifecycleUtils.destroy(getSessionManager()); this.sessionManager = null; super.destroy(); }}
6.DefaultSecurityManager
//默认的SessionManager的具体实现,该实现类会合适的初始化依赖组件。如subjectFactory、SubjectDAOpublic class DefaultSecurityManager extends SessionsSecurityManager { private static final Logger log = LoggerFactory.getLogger(DefaultSecurityManager.class); //是否记住密码服务组件 protected RememberMeManager rememberMeManager; //subject(代理特定的一个用户的所有权限相关操作,登陆退出、授权,获取session等)的管理组件,仅提供了save和delete方法。用于保存subject的状态,方便与以后可以重建subject protected SubjectDAO subjectDAO; //根据SubjectContext(subject的状态和相关的数据)来创建个subject protected SubjectFactory subjectFactory; public DefaultSecurityManager() { super(); this.subjectFactory = new DefaultSubjectFactory(); this.subjectDAO = new DefaultSubjectDAO(); } public DefaultSecurityManager(Realm singleRealm) { this(); setRealm(singleRealm); } //realms 调用子类的 setRealms(realms),至少需要一个。 public DefaultSecurityManager(Collection<Realm> realms) { this(); setRealms(realms); } //获取subjectFactory,主要用于创建subject public SubjectFactory getSubjectFactory() { return subjectFactory; } public void setSubjectFactory(SubjectFactory subjectFactory) { this.subjectFactory = subjectFactory; } //获取subjectDAO,主要用于持久化或者删除subject状态(该状态可用于以后来重建subject) public SubjectDAO getSubjectDAO() { return subjectDAO; } public void setSubjectDAO(SubjectDAO subjectDAO) { this.subjectDAO = subjectDAO; } public RememberMeManager getRememberMeManager() { return rememberMeManager; } public void setRememberMeManager(RememberMeManager rememberMeManager) { this.rememberMeManager = rememberMeManager; } protected SubjectContext createSubjectContext() { return new DefaultSubjectContext(); } //根据形参,创建个subject。 //token用户输入的账户密码,info从数据库加载的账户密码 protected Subject createSubject(AuthenticationToken token, AuthenticationInfo info, Subject existing) { //创建默认的SubjectContext的实现 SubjectContext context = createSubjectContext(); //设置context的是否验证、token和info,方便以后调用 context.setAuthenticated(true); context.setAuthenticationToken(token); context.setAuthenticationInfo(info); if (existing != null) { context.setSubject(existing); } return createSubject(context); } //shiri1.2之后已被弃用 @Deprecated protected void bind(Subject subject) { save(subject); } //执行RememberMeManager的onSuccessfulLogin(subject, token, info) protected void rememberMeSuccessfulLogin(AuthenticationToken token, AuthenticationInfo info, Subject subject) { RememberMeManager rmm = getRememberMeManager(); if (rmm != null) { try { //记住当前subject, principals rmm.onSuccessfulLogin(subject, token, info); } catch (Exception e) { if (log.isWarnEnabled()) { String msg = "Delegate RememberMeManager instance of type [" + rmm.getClass().getName() + "] threw an exception during onSuccessfulLogin. RememberMe services will not be " + "performed for account [" + info + "]."; log.warn(msg, e); } } } else { if (log.isTraceEnabled()) { log.trace("This " + getClass().getName() + " instance does not have a " + "[" + RememberMeManager.class.getName() + "] instance configured. RememberMe services " + "will not be performed for account [" + info + "]."); } } } protected void rememberMeFailedLogin(AuthenticationToken token, AuthenticationException ex, Subject subject) { RememberMeManager rmm = getRememberMeManager(); if (rmm != null) { try { //清除cookie(重置cookie为默认值) rmm.onFailedLogin(subject, token, ex); } catch (Exception e) { if (log.isWarnEnabled()) { String msg = "Delegate RememberMeManager instance of type [" + rmm.getClass().getName() + "] threw an exception during onFailedLogin for AuthenticationToken [" + token + "]."; log.warn(msg, e); } } } } protected void rememberMeLogout(Subject subject) { RememberMeManager rmm = getRememberMeManager(); if (rmm != null) { try { //清除cookie(重置cookie为默认值) rmm.onLogout(subject); } catch (Exception e) { if (log.isWarnEnabled()) { String msg = "Delegate RememberMeManager instance of type [" + rmm.getClass().getName() + "] threw an exception during onLogout for subject with principals [" + (subject != null ? subject.getPrincipals() : null) + "]"; log.warn(msg, e); } } } } /** 用户登陆验证方法 1.首先调用authenticate(token)验证当前用户登陆信息; 2.登陆验证成功后,创建当前用户的subject且绑定到当前线程和把subject的状态信息保存到session中,方便以后重建subject **/ public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info; try { //调用父类AuthenticationSecurityManager的authenticate方法,验证用户是否登陆成功 info = authenticate(token); } catch (AuthenticationException ae) { try { //如果验证失败,重置cookie为初始化值 onFailedLogin(token, ae, subject); } catch (Exception e) { if (log.isInfoEnabled()) { log.info("onFailedLogin method threw an " + "exception. Logging and propagating original AuthenticationException.", e); } } //验证失败,则抛出异常 throw ae; //propagate } //创建subject Subject loggedIn = createSubject(token, info, subject); //设置唯一的principle到cookie中 onSuccessfulLogin(token, info, loggedIn); return loggedIn; } protected void onSuccessfulLogin(AuthenticationToken token, AuthenticationInfo info, Subject subject) { rememberMeSuccessfulLogin(token, info, subject); } protected void onFailedLogin(AuthenticationToken token, AuthenticationException ae, Subject subject) { rememberMeFailedLogin(token, ae, subject); } protected void beforeLogout(Subject subject) { rememberMeLogout(subject); } protected SubjectContext copy(SubjectContext subjectContext) { return new DefaultSubjectContext(subjectContext); } public Subject createSubject(SubjectContext subjectContext) { //复制个subjectContext,不修改原来的subjectContext SubjectContext context = copy(subjectContext); //确保context已设置securityManager context = ensureSecurityManager(context); //确保context已设置session,如果不存在想办法获取已存在的session,然后设置进去 context = resolveSession(context); //确保context已设置Principals,如果未设置则从rememberManager获取,然后设置 context = resolvePrincipals(context); //调用subjectFactory创建subject Subject subject = doCreateSubject(context); //保存subject状态到session save(subject); return subject; } protected Subject doCreateSubject(SubjectContext context) { return getSubjectFactory().createSubject(context); } //调用subjectDAO保存subject状态 protected void save(Subject subject) { this.subjectDAO.save(subject); } //调用subjectDAO删除subject状态 protected void delete(Subject subject) { this.subjectDAO.delete(subject); } @SuppressWarnings({"unchecked"}) protected SubjectContext ensureSecurityManager(SubjectContext context) { if (context.resolveSecurityManager() != null) { log.trace("Context already contains a SecurityManager instance. Returning."); return context; } log.trace("No SecurityManager found in context. Adding self reference."); context.setSecurityManager(this); return context; } //确保session被设置到context @SuppressWarnings({"unchecked"}) protected SubjectContext resolveSession(SubjectContext context) { //如果已经存在session,则直接返回context if (context.resolveSession() != null) { log.debug("Context already contains a session. Returning."); return context; } try { //根据sessionKey从sessionManager获取session Session session = resolveContextSession(context); if (session != null) { context.setSession(session); } } catch (InvalidSessionException e) { log.debug("Resolved SubjectContext context session is invalid. Ignoring and creating an anonymous " + "(session-less) Subject instance.", e); } return context; } //根据sessionKey从sessionManager获取session protected Session resolveContextSession(SubjectContext context) throws InvalidSessionException { SessionKey key = getSessionKey(context); if (key != null) { return getSession(key); } return null; } //获取sessionKey(SID) protected SessionKey getSessionKey(SubjectContext context) { Serializable sessionId = context.getSessionId(); if (sessionId != null) { return new DefaultSessionKey(sessionId); } return null; } @SuppressWarnings({"unchecked"}) protected SubjectContext resolvePrincipals(SubjectContext context) { PrincipalCollection principals = context.resolvePrincipals(); if (CollectionUtils.isEmpty(principals)) { //从Remembered获取principals principals = getRememberedIdentity(context); if (!CollectionUtils.isEmpty(principals)) { context.setPrincipals(principals); } else { log.trace("No remembered identity found. Returning original context."); } } return context; } protected SessionContext createSessionContext(SubjectContext subjectContext) { DefaultSessionContext sessionContext = new DefaultSessionContext(); if (!CollectionUtils.isEmpty(subjectContext)) { sessionContext.putAll(subjectContext); } Serializable sessionId = subjectContext.getSessionId(); if (sessionId != null) { sessionContext.setSessionId(sessionId); } String host = subjectContext.resolveHost(); if (host != null) { sessionContext.setHost(host); } return sessionContext; } //用户退出方法 public void logout(Subject subject) { if (subject == null) { throw new IllegalArgumentException("Subject method argument cannot be null."); } //在执行退出方法前,重置cookie为初始化值 beforeLogout(subject); PrincipalCollection principals = subject.getPrincipals(); if (principals != null && !principals.isEmpty()) { if (log.isDebugEnabled()) { log.debug("Logging out subject with primary principal {}", principals.getPrimaryPrincipal()); } //调用验证器的onLogout方法,目前该方法主要是迭代AuthenticationListener的logout方法 Authenticator authc = getAuthenticator(); if (authc instanceof LogoutAware) { ((LogoutAware) authc).onLogout(principals); } } try { delete(subject); } catch (Exception e) { } finally { try { //设置session过期 stopSession(subject); } catch (Exception e) { } } } //设置session过期 protected void stopSession(Subject subject) { Session s = subject.getSession(false); if (s != null) { s.stop(); } } /** * Unbinds or removes the Subject's state from the application, typically called during {@link #logout}. * <p/> * This has been deprecated in Shiro 1.2 in favor of the {@link #delete(org.apache.shiro.subject.Subject) delete} * method. The implementation has been updated to invoke that method. * * @param subject the subject to unbind from the application as it will no longer be used. * @deprecated in Shiro 1.2 in favor of {@link #delete(org.apache.shiro.subject.Subject)} */ @Deprecated @SuppressWarnings({"UnusedDeclaration"}) protected void unbind(Subject subject) { delete(subject); } //根据SubjectContext从RememberMeManager获取PrincipalCollection protected PrincipalCollection getRememberedIdentity(SubjectContext subjectContext) { RememberMeManager rmm = getRememberMeManager(); if (rmm != null) { try { return rmm.getRememberedPrincipals(subjectContext); } catch (Exception e) { if (log.isWarnEnabled()) { String msg = "Delegate RememberMeManager instance of type [" + rmm.getClass().getName() + "] threw an exception during getRememberedPrincipals()."; log.warn(msg, e); } } } return null; }}
7.DefaultWebSecurityManager
//WebSecurityManager实现被使用在基于web的应用程序中或者需要http请求的应用程序中(如SOAP,http remoting, etc)public class DefaultWebSecurityManager extends DefaultSecurityManager implements WebSecurityManager { private static final Logger log = LoggerFactory.getLogger(DefaultWebSecurityManager.class); @Deprecated public static final String HTTP_SESSION_MODE = "http"; @Deprecated public static final String NATIVE_SESSION_MODE = "native"; /** * @deprecated as of 1.2. This should NOT be used for anything other than determining if the sessionMode has changed. */ @Deprecated private String sessionMode; public DefaultWebSecurityManager() { super(); //设置SessionStorageEvaluator(评估Session是否需要存储,在无状态环境下可以设置为false,如Rest架构)到DefaultSubjectDAO ((DefaultSubjectDAO) this.subjectDAO).setSessionStorageEvaluator(new DefaultWebSessionStorageEvaluator()); this.sessionMode = HTTP_SESSION_MODE; //初始化基于WEB的DefaultWebSubjectFactory setSubjectFactory(new DefaultWebSubjectFactory()); setRememberMeManager(new CookieRememberMeManager()); //默认是 基于servlet的session的sessionManaer,即不使用shiro自己管理的session setSessionManager(new ServletContainerSessionManager()); } @SuppressWarnings({"UnusedDeclaration"}) public DefaultWebSecurityManager(Realm singleRealm) { this(); setRealm(singleRealm); } @SuppressWarnings({"UnusedDeclaration"}) public DefaultWebSecurityManager(Collection<Realm> realms) { this(); setRealms(realms); } @Override protected SubjectContext createSubjectContext() { return new DefaultWebSubjectContext(); } @Override //since 1.2.1 for fixing SHIRO-350 public void setSubjectDAO(SubjectDAO subjectDAO) { super.setSubjectDAO(subjectDAO); //设置sessionManager到DefaultSubjectDAO的SessionStorageEvaluator applySessionManagerToSessionStorageEvaluatorIfPossible(); } //在sessionManager被设置后,设置sessionManager到DefaultSubjectDAO的SessionStorageEvaluator @Override protected void afterSessionManagerSet() { super.afterSessionManagerSet(); applySessionManagerToSessionStorageEvaluatorIfPossible(); } //设置sessionManager到DefaultSubjectDAO的SessionStorageEvaluator private void applySessionManagerToSessionStorageEvaluatorIfPossible() { SubjectDAO subjectDAO = getSubjectDAO(); if (subjectDAO instanceof DefaultSubjectDAO) { SessionStorageEvaluator evaluator = ((DefaultSubjectDAO)subjectDAO).getSessionStorageEvaluator(); if (evaluator instanceof DefaultWebSessionStorageEvaluator) { ((DefaultWebSessionStorageEvaluator)evaluator).setSessionManager(getSessionManager()); } } } @Override protected SubjectContext copy(SubjectContext subjectContext) { if (subjectContext instanceof WebSubjectContext) { return new DefaultWebSubjectContext((WebSubjectContext) subjectContext); } return super.copy(subjectContext); } @SuppressWarnings({"UnusedDeclaration"}) @Deprecated public String getSessionMode() { return sessionMode; } /** * @param sessionMode * @deprecated since 1.2 */ @Deprecated public void setSessionMode(String sessionMode) { log.warn("The 'sessionMode' property has been deprecated. Please configure an appropriate WebSessionManager " + "instance instead of using this property. This property/method will be removed in a later version."); String mode = sessionMode; if (mode == null) { throw new IllegalArgumentException("sessionMode argument cannot be null."); } mode = sessionMode.toLowerCase(); if (!HTTP_SESSION_MODE.equals(mode) && !NATIVE_SESSION_MODE.equals(mode)) { String msg = "Invalid sessionMode [" + sessionMode + "]. Allowed values are " + "public static final String constants in the " + getClass().getName() + " class: '" + HTTP_SESSION_MODE + "' or '" + NATIVE_SESSION_MODE + "', with '" + HTTP_SESSION_MODE + "' being the default."; throw new IllegalArgumentException(msg); } boolean recreate = this.sessionMode == null || !this.sessionMode.equals(mode); this.sessionMode = mode; if (recreate) { LifecycleUtils.destroy(getSessionManager()); SessionManager sessionManager = createSessionManager(mode); this.setInternalSessionManager(sessionManager); } } @Override public void setSessionManager(SessionManager sessionManager) { this.sessionMode = null; if (sessionManager != null && !(sessionManager instanceof WebSessionManager)) { if (log.isWarnEnabled()) { String msg = "The " + getClass().getName() + " implementation expects SessionManager instances " + "that implement the " + WebSessionManager.class.getName() + " interface. The " + "configured instance is of type [" + sessionManager.getClass().getName() + "] which does not " + "implement this interface.. This may cause unexpected behavior."; log.warn(msg); } } setInternalSessionManager(sessionManager); } /** * @param sessionManager * @since 1.2 */ private void setInternalSessionManager(SessionManager sessionManager) { super.setSessionManager(sessionManager); } //判断是否是使用httpSession public boolean isHttpSessionMode() { SessionManager sessionManager = getSessionManager(); return sessionManager instanceof WebSessionManager && ((WebSessionManager)sessionManager).isServletContainerSessions(); } protected SessionManager createSessionManager(String sessionMode) { if (sessionMode == null || !sessionMode.equalsIgnoreCase(NATIVE_SESSION_MODE)) { log.info("{} mode - enabling ServletContainerSessionManager (HTTP-only Sessions)", HTTP_SESSION_MODE); return new ServletContainerSessionManager(); } else { log.info("{} mode - enabling DefaultWebSessionManager (non-HTTP and HTTP Sessions)", NATIVE_SESSION_MODE); return new DefaultWebSessionManager(); } } @Override protected SessionContext createSessionContext(SubjectContext subjectContext) { SessionContext sessionContext = super.createSessionContext(subjectContext); if (subjectContext instanceof WebSubjectContext) { WebSubjectContext wsc = (WebSubjectContext) subjectContext; ServletRequest request = wsc.resolveServletRequest(); ServletResponse response = wsc.resolveServletResponse(); DefaultWebSessionContext webSessionContext = new DefaultWebSessionContext(sessionContext); if (request != null) { webSessionContext.setServletRequest(request); } if (response != null) { webSessionContext.setServletResponse(response); } sessionContext = webSessionContext; } return sessionContext; } @Override protected SessionKey getSessionKey(SubjectContext context) { if (WebUtils.isWeb(context)) { Serializable sessionId = context.getSessionId(); ServletRequest request = WebUtils.getRequest(context); ServletResponse response = WebUtils.getResponse(context); return new WebSessionKey(sessionId, request, response); } else { return super.getSessionKey(context); } } @Override protected void beforeLogout(Subject subject) { super.beforeLogout(subject); removeRequestIdentity(subject); } protected void removeRequestIdentity(Subject subject) { if (subject instanceof WebSubject) { WebSubject webSubject = (WebSubject) subject; ServletRequest request = webSubject.getServletRequest(); if (request != null) { request.setAttribute(ShiroHttpServletRequest.IDENTITY_REMOVED_KEY, Boolean.TRUE); } } }}
2 0
- 2.详解SecurityManager(shiro权限管理门面)
- 【Shiro权限管理】13. SecurityManager配置realms
- Shiro详解之SecurityManager
- 【Shiro】SpringMVC+Shiro权限管理
- shiro securityManager结构
- Shiro源码之SecurityManager
- 【Shiro权限管理】2.Shiro的HelloWorld程序
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- shiro管理端权限
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- SpringMVC+Shiro权限管理
- 恶意程序威胁程度“五芒星”评估法
- C++ 用libcurl库进行http 网络通讯编程
- 软工视频总结
- 使用libcurl进行文件上传
- eclipse的debug使用技巧
- 2.详解SecurityManager(shiro权限管理门面)
- ztree 动态加载
- objective-c 实现常用算法(冒泡、选择、快速、插入)
- Xilinx FPGA FFT 应用笔记
- Ejb之实体管理器
- Uva-297 - Quadtrees(四分树与结构体指针)
- HDU 3594
- Java- 断言及程序的测试JUnit
- OC基础-零基础学习Objective-C:第四部分.NSArray