zoukankan      html  css  js  c++  java
  • 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

        忘记是哪个写的了。

  • 相关阅读:
    使用 Redis 实现分布式锁(转载)
    使用Redis SETNX 命令实现分布式锁(转载)
    linux目录(转载)
    sleep函数作用(转)
    大数据量高并发的数据库优化(转)
    java获取request的url方法区别
    java获取request的头信息
    打分排序系统漫谈2
    打分排序系统漫谈1
    Tree
  • 原文地址:https://www.cnblogs.com/xyzxy/p/13523893.html
Copyright © 2011-2022 走看看