• shiro会话管理


    一、会话管理

    shiro的会话管理具备Tomcat的会话管理的一切功能,同时相较于Tomcat的session,shiro提供了对于分布式session的管理

    1.1会话监听器 

    1. package com.liaoxin.ssm.shiro;
    2. import org.apache.shiro.session.Session;
    3. import org.apache.shiro.session.SessionListener;
    4. /**
    5. * @author liaoxin
    6. * @create 2022-08-27 11:16
    7. */
    8. public class ShiroSessionListener implements SessionListener {
    9. @Override
    10. public void onStart(Session session) {
    11. System.out.println("ShiroSessionListener.onstart..."+session.getId());
    12. }
    13. @Override
    14. public void onStop(Session session) {
    15. System.out.println("ShiroSessionListener.onStop..."+session.getId());
    16. }
    17. @Override
    18. public void onExpiration(Session session) {
    19. System.out.println("ShiroSessionListener.onExpiration..."+session.getId());
    20. }
    21. }

     1.2 Spring-shiro.xml

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    5. <bean id="shiroRealm" class="com.liaoxin.ssm.shiro.Myrealm">
    6. <property name="userBiz" ref="UserService" />
    7. <property name="credentialsMatcher">
    8. <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
    9. <property name="hashAlgorithmName" value="md5"/>
    10. <property name="hashIterations" value="1024"/>
    11. <property name="storedCredentialsHexEncoded" value="true"/>
    12. bean>
    13. property>
    14. bean>
    15. <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    16. <property name="realm" ref="shiroRealm" />
    17. <property name="sessionManager" ref="sessionManager">property>
    18. bean>
    19. <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    20. <property name="securityManager" ref="securityManager" />
    21. <property name="loginUrl" value="/login"/>
    22. <property name="unauthorizedUrl" value="/unauthorized.jsp"/>
    23. <property name="filterChainDefinitions">
    24. <value>
    25. /user/login=anon
    26. /user/updatePwd.jsp=authc
    27. /admin/*.jsp=roles[4]
    28. /user/teacher.jsp=perms[2]
    29. value>
    30. property>
    31. bean>
    32. <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    33. <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator">
    34. bean>
    35. <bean id="customSessionDao" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO">
    36. <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    37. bean>
    38. <bean id="shiroSessionListener" class="com.liaoxin.ssm.shiro.ShiroSessionListener"/>
    39. <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
    40. <constructor-arg value="shiro.session"/>
    41. <property name="maxAge" value="-1"/>
    42. <property name="httpOnly" value="true"/>
    43. bean>
    44. <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    45. <property name="globalSessionTimeout" value="120000"/>
    46. <property name="sessionDAO" ref="customSessionDao"/>
    47. <property name="sessionValidationInterval" value="60000"/>
    48. <property name="deleteInvalidSessions" value="true"/>
    49. <property name="sessionListeners">
    50. <list>
    51. <ref bean="shiroSessionListener"/>
    52. list>
    53. property>
    54. <property name="sessionIdCookie" ref="sessionIdCookie"/>
    55. <property name="sessionIdUrlRewritingEnabled" value="false"/>
    56. bean>
    57. <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    58. <property name="configLocation" value="classpath:ehcache.xml"/>
    59. <property name="shared" value="true"/>
    60. bean>
    61. <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
    62. <property name="cacheManager" ref="cacheManagerFactory"/>
    63. bean>
    64. beans>

     1.3 测试

    ①当登录发送请求 会执行 监听器中的 onstart
    ②当登出发送请求 会执行 监听器中的 onStop
    ③当检查session过期时,会执行 监听器中的 onExpiration
    ④过期时,需要身份验证才能访问的方法,就不会被允许访问;

     

     

     

    二、缓存管理

    缓存策略

    1.默认基于内存,即服务停止,缓存数据丢失

    2.基于文件存储

    解决反复授权查询数据库的问题

    2.1 初识缓存 

    1. package com.liaoxin.ssm.ehcache;
    2. import java.util.HashMap;
    3. import java.util.Map;
    4. /**
    5. * 利用map集合简易实现缓存原理
    6. * @author Administrator
    7. *
    8. */
    9. public class EhcacheDemo1 {
    10. static Map cache = new HashMap();
    11. static Object getValue(String key) {
    12. Object value = cache.get(key);
    13. if(value == null) {
    14. System.out.println("hello zs");
    15. cache.put(key, new String[] {"zs"});
    16. return cache.get(key);
    17. }
    18. return value;
    19. }
    20. public static void main(String[] args) {
    21. System.out.println(getValue("sname"));
    22. System.out.println(getValue("sname"));
    23. }
    24. }

    2.2 ehcache.xml介绍

    1. "1.0" encoding="UTF-8"?>
    2. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
    4. updateCheck="false">
    5. <diskStore path="D://xxx"/>
    6. <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
    7. timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
    8. <cache name="com.javaxl.one.entity.User" eternal="false" maxElementsInMemory="100"
    9. overflowToDisk="true" diskPersistent="true" timeToIdleSeconds="0"
    10. timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU"/>
    11. ehcache>

    2.3 Ehcache的初步使用

    1. package com.liaoxin.ssm.ehcache;
    2. import net.sf.ehcache.Cache;
    3. import net.sf.ehcache.CacheManager;
    4. import net.sf.ehcache.Element;
    5. import java.io.InputStream;
    6. public class EhcacheUtil {
    7. private static CacheManager cacheManager;
    8. static {
    9. try {
    10. InputStream is = EhcacheUtil.class.getResourceAsStream("/ehcache.xml");
    11. cacheManager = CacheManager.create(is);
    12. } catch (Exception e) {
    13. throw new RuntimeException(e);
    14. }
    15. }
    16. private EhcacheUtil() {
    17. }
    18. public static void put(String cacheName, Object key, Object value) {
    19. Cache cache = cacheManager.getCache(cacheName);
    20. if (null == cache) {
    21. //以默认配置添加一个名叫cacheName的Cache
    22. cacheManager.addCache(cacheName);
    23. cache = cacheManager.getCache(cacheName);
    24. }
    25. cache.put(new Element(key, value));
    26. }
    27. public static Object get(String cacheName, Object key) {
    28. Cache cache = cacheManager.getCache(cacheName);
    29. if (null == cache) {
    30. //以默认配置添加一个名叫cacheName的Cache
    31. cacheManager.addCache(cacheName);
    32. cache = cacheManager.getCache(cacheName);
    33. }
    34. Element element = cache.get(key);
    35. return null == element ? null : element.getValue();
    36. }
    37. public static void remove(String cacheName, Object key) {
    38. Cache cache = cacheManager.getCache(cacheName);
    39. cache.remove(key);
    40. }
    41. }

    演示ehcache的使用

    1. package com.liaoxin.ssm.ehcache;
    2. /**
    3. * 演示利用缓存存储数据
    4. * @author Administrator
    5. *
    6. */
    7. public class EhcacheDemo2 {
    8. public static void main(String[] args) {
    9. System.out.println(System.getProperty("java.io.tmpdir"));
    10. // EhcacheUtil.put("com.javaxl.four.entity.Book", 11, "zhangsan");
    11. // System.out.println(EhcacheUtil.get("com.javaxl.four.entity.Book", 11));
    12. EhcacheUtil.put("com.javaxl.one.entity.User", 11, "zhangsan");
    13. System.out.println(EhcacheUtil.get("com.javaxl.one.entity.User", 11));
    14. }
    15. }

    2.4 Ehcache完成realm授权

    1. package com.liaoxin.ssm.shiro;
    2. import com.liaoxin.ssm.biz.UserBiz;
    3. import com.liaoxin.ssm.ehcache.EhcacheUtil;
    4. import com.liaoxin.ssm.model.User;
    5. import org.apache.shiro.authc.AuthenticationException;
    6. import org.apache.shiro.authc.AuthenticationInfo;
    7. import org.apache.shiro.authc.AuthenticationToken;
    8. import org.apache.shiro.authc.SimpleAuthenticationInfo;
    9. import org.apache.shiro.authz.AuthorizationInfo;
    10. import org.apache.shiro.authz.SimpleAuthorizationInfo;
    11. import org.apache.shiro.realm.AuthorizingRealm;
    12. import org.apache.shiro.subject.PrincipalCollection;
    13. import org.apache.shiro.util.ByteSource;
    14. import java.util.Set;
    15. /**
    16. * @author liaoxin
    17. * @create 2022-08-25 18:16
    18. */
    19. public class Myrealm extends AuthorizingRealm {
    20. private UserBiz userBiz;
    21. public UserBiz getUserBiz() {
    22. return userBiz;
    23. }
    24. public void setUserBiz(UserBiz userBiz) {
    25. this.userBiz = userBiz;
    26. }
    27. @Override
    28. protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    29. System.out.println("用户授权...");
    30. String username = principals.getPrimaryPrincipal().toString();
    31. User user = userBiz.queryByName(username);
    32. String user_role_key = "user:roles:";
    33. String user_pers_key = "user:pers:";
    34. Set roles = userBiz.getRolesByUserId(user.getUsername());
    35. Set pers = userBiz.getPersByUserId(user.getUsername());
    36. if(roles == null||roles.size()==0){
    37. System.out.println("从数据库中获取相关角色信息...");
    38. roles=userBiz.getRolesByUserId(user.getUsername());
    39. EhcacheUtil.put(user_role_key+user.getUserid(),user.getUserid(),roles);
    40. }
    41. if(pers==null||pers.size()==0){
    42. System.out.println("从数据库中获取相关权限信息...");
    43. pers=userBiz.getPersByUserId(user.getUsername());
    44. EhcacheUtil.put(user_pers_key+user.getUserid(),user.getUserid(),pers);
    45. }
    46. SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
    47. info.setRoles(roles);
    48. info.setStringPermissions(pers);
    49. return info;
    50. }
    51. @Override
    52. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    53. System.out.println("身份验证...");
    54. String username = token.getPrincipal().toString();
    55. String password = token.getCredentials().toString();
    56. User user = userBiz.queryByName(username);
    57. AuthenticationInfo info=new SimpleAuthenticationInfo(
    58. user.getUsername(),
    59. user.getPassword(),
    60. ByteSource.Util.bytes(user.getSalt()),
    61. this.getName()
    62. );
    63. return info;
    64. }
    65. }

    测试会发现,只有第一次执行授权方法的时候,才会从数据库中获取用户信息,其他时候都是从缓存中拿数据; 

  • 相关阅读:
    「企企通」完成Pre-D轮融资,加速采购供应链工业软件和 SaaS 网络生态构建
    使用kubeadm快速部署一个k8s集群
    突破卡脖子技术 AVS3标准在世界杯实现移动端规模化商用
    apache 漏洞
    Linux 基础-新手必备命令
    Eureka应用及高可用集群
    [BAT-表姐御用02tree命令】提取目录文件夹及其子文件后,tree形列出
    任务调度之Timer定时器源码分析
    【使用matplotlib】使用函数绘制matplotlib的图片组成元素
    《思科 - GNS3 - Pythonping》
  • 原文地址:https://blog.csdn.net/qq_44247968/article/details/126601129