系统通过AOP切入权限认证后,既想保证安全,也想保证访问页面的速度,那就得用到缓存了,或者说是缓冲区。
用户第一次登陆后,将该用户所具有的所有权限缓存到本地。这样,频繁的验证用户是否具有操作权限时,不再每次都到数据库拿数据。
在OA项目中的权限,是每次用户操作前,先到数据库中取得该用户拥有的权限,然后判断其操作是否合法。这样的频繁的读取数据,必然降低了页面的访问速度。
虽然Shrio缺省提供了基于ehCache来缓存用户认证信息和授权信息的实现,还记得EhCache是Hibernate的二级缓存技术之一。但还是提倡显示配置缓存,因为一眼就能看出使用了缓存,并且可以设置参数。
<!--用户授权/认证信息Cache, 采用EhCache 缓存 -->
<beanid="shiroEhcacheManager"class="org.apache.shiro.cache.ehcache.EhCacheManager">
<propertyname="cacheManagerConfigFile"value="classpath:ehcache-shiro.xml"/>
</bean>
<beanid="securityManager"class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!--Single realm app. If you have multiplerealms, use the 'realms' property instead. -->
<propertyname="realm" ref="shiroDbRealm" />
<propertyname="cacheManager" ref="shiroEhcacheManager" />
</bean>
<ehcacheupdateCheck="false" name="shiroCache">
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskSpoolBufferSizeMB="50"
diskExpiryThreadIntervalSeconds="120"
/>
</ehcache>
maxElementsInMemory:内存允许的最大存储缓存数,如果超过,在开启磁盘存储的情况下,会存入磁盘
eternal:对象是否永久有效
timeToIdleSeconds:对象允许空闲时间(秒),当且仅当eternal=fasle时起效,如果值为0,表示可闲置时间无穷大
timeToLiveSeconds:对象允许存活时间(秒),当且仅当eternal=fasle时起效,如果值为0,表示可闲置时间无穷大,配置值应该大于空闲时间值,否则没有意义
overflowToDisk:内存中缓存数超过最大值之后是否允许存入磁盘
diskSpoolBufferSizeMB:磁盘缓存的缓存区大小
diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false
这是登录页面,可以使用admin和test登录,但他们具有不同权限
通过admin登陆后,控制台显示:
====================doGetAuthenticationInfobegin ==========================
username:admin
password:admin
principal:admin
======================doGetAuthenticationInfoend ========================
由于加入了缓存,此处只会load一次:doGetAuthorizationInfo.................
显示的信息说明,是使用admin登录的,而无论admin再做什么操作,doGetAuthorizationInfo(验证权限的方法)只执行一次。
admin登录后看到的页面(test无权限访问)
admin如果没有logout,又通过test登陆,此时控制台并没有打印认证信息,test看到的界面就是刚才admin看到的界面,也就是具有相同的权限(本来是不同的)。
因为没有logout,EhCache缓存shiro会话(包括登陆和权限等信息),sessionId是一样的,也就不会执行登陆认证(doGetAuthenticationInfo)和授权认证(doGetAuthorizationInfo)
所以,缓存及时清理工作很重要。用户在安全退出和没有安全退出情况下,都得保证缓存的清理工作。
缓存是把双刃剑,给带来高效的同时,也留下了隐患。
当用户没有安全退出就直接关闭浏览器,会话可能在缓存里孤立,如何解决?敬请期待!