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

    忘記是哪個寫的了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM