shiro的会话管理具备Tomcat的会话管理的一切功能,同时相较于Tomcat的session,shiro提供了对于分布式session的管理
- package com.liaoxin.ssm.shiro;
-
- import org.apache.shiro.session.Session;
- import org.apache.shiro.session.SessionListener;
-
- /**
- * @author liaoxin
- * @create 2022-08-27 11:16
- */
- public class ShiroSessionListener implements SessionListener {
- @Override
- public void onStart(Session session) {
- System.out.println("ShiroSessionListener.onstart..."+session.getId());
- }
-
- @Override
- public void onStop(Session session) {
- System.out.println("ShiroSessionListener.onStop..."+session.getId());
- }
-
- @Override
- public void onExpiration(Session session) {
- System.out.println("ShiroSessionListener.onExpiration..."+session.getId());
- }
- }
-
- "1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
-
- <bean id="shiroRealm" class="com.liaoxin.ssm.shiro.Myrealm">
- <property name="userBiz" ref="UserService" />
-
-
-
-
- <property name="credentialsMatcher">
- <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
-
- <property name="hashAlgorithmName" value="md5"/>
-
- <property name="hashIterations" value="1024"/>
-
- <property name="storedCredentialsHexEncoded" value="true"/>
- bean>
- property>
- bean>
-
-
-
- <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
- <property name="realm" ref="shiroRealm" />
- <property name="sessionManager" ref="sessionManager">property>
- bean>
-
-
- <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
-
- <property name="securityManager" ref="securityManager" />
-
- <property name="loginUrl" value="/login"/>
-
-
-
- <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
-
- <property name="filterChainDefinitions">
- <value>
-
-
-
-
- /user/login=anon
- /user/updatePwd.jsp=authc
- /admin/*.jsp=roles[4]
- /user/teacher.jsp=perms[2]
-
- value>
- property>
- bean>
-
-
- <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
-
-
- <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator">
- bean>
-
-
- <bean id="customSessionDao" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO">
- <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
- bean>
-
-
- <bean id="shiroSessionListener" class="com.liaoxin.ssm.shiro.ShiroSessionListener"/>
-
-
- <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
-
- <constructor-arg value="shiro.session"/>
-
- <property name="maxAge" value="-1"/>
-
- <property name="httpOnly" value="true"/>
- bean>
-
-
- <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
-
- <property name="globalSessionTimeout" value="120000"/>
-
- <property name="sessionDAO" ref="customSessionDao"/>
-
- <property name="sessionValidationInterval" value="60000"/>
-
-
-
-
-
- <property name="deleteInvalidSessions" value="true"/>
-
- <property name="sessionListeners">
- <list>
- <ref bean="shiroSessionListener"/>
- list>
- property>
-
- <property name="sessionIdCookie" ref="sessionIdCookie"/>
-
- <property name="sessionIdUrlRewritingEnabled" value="false"/>
- bean>
-
-
- <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
- <property name="configLocation" value="classpath:ehcache.xml"/>
- <property name="shared" value="true"/>
- bean>
-
- <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
- <property name="cacheManager" ref="cacheManagerFactory"/>
- bean>
- beans>
-
-
①当登录发送请求 会执行 监听器中的 onstart
②当登出发送请求 会执行 监听器中的 onStop
③当检查session过期时,会执行 监听器中的 onExpiration
④过期时,需要身份验证才能访问的方法,就不会被允许访问;


缓存策略
1.默认基于内存,即服务停止,缓存数据丢失
2.基于文件存储
解决反复授权查询数据库的问题
- package com.liaoxin.ssm.ehcache;
-
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * 利用map集合简易实现缓存原理
- * @author Administrator
- *
- */
- public class EhcacheDemo1 {
- static Map
cache = new HashMap(); - static Object getValue(String key) {
- Object value = cache.get(key);
- if(value == null) {
- System.out.println("hello zs");
- cache.put(key, new String[] {"zs"});
- return cache.get(key);
- }
- return value;
- }
-
- public static void main(String[] args) {
- System.out.println(getValue("sname"));
- System.out.println(getValue("sname"));
- }
- }
-
- "1.0" encoding="UTF-8"?>
- <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
- updateCheck="false">
-
-
-
- <diskStore path="D://xxx"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
- <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
- timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
-
-
-
- <cache name="com.javaxl.one.entity.User" eternal="false" maxElementsInMemory="100"
- overflowToDisk="true" diskPersistent="true" timeToIdleSeconds="0"
- timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU"/>
- ehcache>
-
- package com.liaoxin.ssm.ehcache;
-
- import net.sf.ehcache.Cache;
- import net.sf.ehcache.CacheManager;
- import net.sf.ehcache.Element;
-
- import java.io.InputStream;
-
- public class EhcacheUtil {
-
- private static CacheManager cacheManager;
-
- static {
- try {
- InputStream is = EhcacheUtil.class.getResourceAsStream("/ehcache.xml");
- cacheManager = CacheManager.create(is);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- private EhcacheUtil() {
- }
-
- public static void put(String cacheName, Object key, Object value) {
- Cache cache = cacheManager.getCache(cacheName);
- if (null == cache) {
- //以默认配置添加一个名叫cacheName的Cache
- cacheManager.addCache(cacheName);
- cache = cacheManager.getCache(cacheName);
- }
- cache.put(new Element(key, value));
- }
-
-
- public static Object get(String cacheName, Object key) {
- Cache cache = cacheManager.getCache(cacheName);
- if (null == cache) {
- //以默认配置添加一个名叫cacheName的Cache
- cacheManager.addCache(cacheName);
- cache = cacheManager.getCache(cacheName);
- }
- Element element = cache.get(key);
- return null == element ? null : element.getValue();
- }
-
- public static void remove(String cacheName, Object key) {
- Cache cache = cacheManager.getCache(cacheName);
- cache.remove(key);
- }
- }
-
演示ehcache的使用
- package com.liaoxin.ssm.ehcache;
-
-
- /**
- * 演示利用缓存存储数据
- * @author Administrator
- *
- */
- public class EhcacheDemo2 {
- public static void main(String[] args) {
- System.out.println(System.getProperty("java.io.tmpdir"));
- // EhcacheUtil.put("com.javaxl.four.entity.Book", 11, "zhangsan");
- // System.out.println(EhcacheUtil.get("com.javaxl.four.entity.Book", 11));
-
- EhcacheUtil.put("com.javaxl.one.entity.User", 11, "zhangsan");
- System.out.println(EhcacheUtil.get("com.javaxl.one.entity.User", 11));
-
- }
- }
-
- package com.liaoxin.ssm.shiro;
-
- import com.liaoxin.ssm.biz.UserBiz;
- import com.liaoxin.ssm.ehcache.EhcacheUtil;
- import com.liaoxin.ssm.model.User;
- import org.apache.shiro.authc.AuthenticationException;
- import org.apache.shiro.authc.AuthenticationInfo;
- import org.apache.shiro.authc.AuthenticationToken;
- import org.apache.shiro.authc.SimpleAuthenticationInfo;
- import org.apache.shiro.authz.AuthorizationInfo;
- import org.apache.shiro.authz.SimpleAuthorizationInfo;
- import org.apache.shiro.realm.AuthorizingRealm;
- import org.apache.shiro.subject.PrincipalCollection;
- import org.apache.shiro.util.ByteSource;
-
- import java.util.Set;
-
- /**
- * @author liaoxin
- * @create 2022-08-25 18:16
- */
- public class Myrealm extends AuthorizingRealm {
- private UserBiz userBiz;
-
- public UserBiz getUserBiz() {
- return userBiz;
- }
-
- public void setUserBiz(UserBiz userBiz) {
- this.userBiz = userBiz;
- }
-
- @Override
- protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
- System.out.println("用户授权...");
- String username = principals.getPrimaryPrincipal().toString();
- User user = userBiz.queryByName(username);
- String user_role_key = "user:roles:";
- String user_pers_key = "user:pers:";
- Set
roles = userBiz.getRolesByUserId(user.getUsername()); - Set
pers = userBiz.getPersByUserId(user.getUsername()); - if(roles == null||roles.size()==0){
- System.out.println("从数据库中获取相关角色信息...");
- roles=userBiz.getRolesByUserId(user.getUsername());
- EhcacheUtil.put(user_role_key+user.getUserid(),user.getUserid(),roles);
- }
- if(pers==null||pers.size()==0){
- System.out.println("从数据库中获取相关权限信息...");
- pers=userBiz.getPersByUserId(user.getUsername());
- EhcacheUtil.put(user_pers_key+user.getUserid(),user.getUserid(),pers);
- }
- SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
- info.setRoles(roles);
- info.setStringPermissions(pers);
- return info;
- }
-
- @Override
- protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
- System.out.println("身份验证...");
- String username = token.getPrincipal().toString();
- String password = token.getCredentials().toString();
- User user = userBiz.queryByName(username);
- AuthenticationInfo info=new SimpleAuthenticationInfo(
- user.getUsername(),
- user.getPassword(),
- ByteSource.Util.bytes(user.getSalt()),
- this.getName()
- );
- return info;
- }
- }
-
测试会发现,只有第一次执行授权方法的时候,才会从数据库中获取用户信息,其他时候都是从缓存中拿数据;