• Springboot中Shiro自定义jsessionId


    今天突然想到一个问题关于前后不分shiro的WEB项目sessionid安全问题.

    前后分离可以使用token作为用户唯一标志凭证,这个token可以自定义生成规则,

    那么前后不分的shiro项目返回的是一串32位的字符串,

    我们这里假设攻击方客户端足够多,服务端用户足够多,

    那么在一定时间,攻击方无限访问服务端。是否会命中正确的sessionid。

    这里,就想着自定义session生成规则。

    下面说一下思路。

    Springboot整合Shiro的案例以及Shiro架构网上很多。这里就不说了。

    1.DefaultWebSecurityManager

        /**
         * 注入 securityManager
         */
        @Bean(name="securityManager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(HashedCredentialsMatcher hashedCredentialsMatcher,SessionManager defaultWebSessionManager) {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            // 关联realm.
            securityManager.setRealm(userRealm(hashedCredentialsMatcher));
            
            securityManager.setSessionManager(defaultWebSessionManager);
            return securityManager;
        }
    

     此段代码是必须的,我们这里需要重新自定义SessionMannager里面的一些实现。因为session是SessionMannager生成的

    2.观察setSessionManager方法

        @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);
        }
    

     此处传入的对象需要是WebSessionManager实例

    3.观察WebSessionManager继承实现关系,发现DefaultWebSessionManager的父类DefaultSessionManager 有个protected SessionDAO sessionDAO;属性

    4.观察SessionDAO继承实现关系抽象类有个SessionIdGenerator接口,这个就是我们需要自己定义的sessionid生成策略了。

    5.自定义生成策略

    public class SessionIdMine implements SessionIdGenerator{
    
    	@Override
    	public Serializable generateId(Session session) {
    		return UUID.randomUUID().toString();
    	}
    
    }
    

    6.将此策略给Spring容器管理

       @Bean(name="sessionDAO")
        public EnterpriseCacheSessionDAO sessionDAO() {
        	EnterpriseCacheSessionDAO abstractSessionDAO=new EnterpriseCacheSessionDAO();
        	abstractSessionDAO.setSessionIdGenerator(new SessionIdMine());
        	return abstractSessionDAO;
    	}
    

     EnterpriseCacheSessionDAO为SessionDAO的子类这里需要返回子类作为下一步参数传递

     7.思考如何将自定义策略实现到shiro,前面说到DefaultWebSessionManager为WebSessionManager最底层实现类,DefaultSessionManager子类,

    将DefaultWebSessionManager给Spring管理

        @Bean(name="defaultWebSessionManager")
        public DefaultWebSessionManager defaultWebSessionManager(EnterpriseCacheSessionDAO sessionDAO) {
        	DefaultWebSessionManager abstractSessionDAO=new DefaultWebSessionManager();
        	abstractSessionDAO.setSessionDAO(sessionDAO);
        	return abstractSessionDAO;
    	}
    

    8.至此自定义策略完成,网上观察了一些方法,版本不同实现不同,大体思路就是追源码,看实现

    9.效果

    10.补充一下Shirodemo测试地址

        https://github.com/Rhine404/shirodemo.git

        忘记是哪个写的了。

  • 相关阅读:
    C# 反射数据库数据过程中值类型存在DBNull的处理方法 == System.DBNull.Value
    Git 未能顺利结束 (退出码 128)解决办法 git常用命令流程图
    IDEA之The directory xxxxx is under Git, but is not registered in the Settings.
    git push提交成功后如何撤销回退 我是手动修改再提交一次 。。或者IDEA有代码修改历史记录功能 进行回退
    IDEA,发现Project文件目录不见了,只剩External Libraries的原因
    分布式事务 seata
    idea设置类,方法模板 阿里检测
    随笔
    初学一点点空间分解和有理标准型
    Vue2+Cesium1.9+热力图开发笔记
  • 原文地址:https://www.cnblogs.com/xyzxy/p/13523893.html
Copyright © 2020-2023  润新知