Shiro功能應用(四)--Session管理及在線人數統計


     Cookie/Session 是常見的狀態管理,Shiro提供了完整的企業級會話管理功能。     本文在上一篇文章Shiro功能應用(三)–EHCache緩存代碼基礎進行添加Session管理。

代碼實現:

      代碼地址:
          https://github.com/OooooOz/SpringBoot-Shiro

     ShiroConfig的安全管理器SecurityManager:

 @Bean(name="securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("shiroRealm") MyShiroRealm shiroRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(shiroRealm);
        securityManager.setRememberMeManager(rememberMeManager());	    //實現記住我
        securityManager.setCacheManager(getEhCacheManager());			//實現緩存
        securityManager.setSessionManager(sessionManager());			//session管理
        return securityManager;
    }

     ShiroConfig的會話管理器sessionManager:

 @Bean("sessionManager")
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        Collection<SessionListener> listeners = new ArrayList<SessionListener>();
        listeners.add(sessionListener());                           //配置監聽
        sessionManager.setSessionListeners(listeners);

        sessionManager.setSessionIdCookie(sessionIdCookie());
        sessionManager.setSessionDAO(sessionDAO());
        sessionManager.setCacheManager(getEhCacheManager());
	    sessionManager.setGlobalSessionTimeout(10000);	            //全局會話超時時間(單位毫秒),默認30分鐘  暫時設置爲10秒鐘 用來測試
        sessionManager.setDeleteInvalidSessions(true);          	//是否開啓刪除無效的session對象  默認爲true
//	    sessionManager.setSessionValidationSchedulerEnabled(true);  //是否開啓定時調度器進行檢測過期session 默認爲true
        //設置session失效的掃描時間, 清理用戶直接關閉瀏覽器造成的孤立會話 默認爲 1個小時
//	    sessionManager.setSessionValidationInterval(5000);	 	    //暫時設置爲 5秒 用來測試
        sessionManager.setSessionIdUrlRewritingEnabled(false);		//取消url 後面的 JSESSIONID
        return sessionManager;
    }

     ShiroConfig的session監聽:

 @Bean("sessionListener")
    public ShiroSessionListener sessionListener(){
        ShiroSessionListener sessionListener = new ShiroSessionListener();
        return sessionListener;
    }

     ShiroConfig的SessionDAO:

 @Bean
    public SessionDAO sessionDAO() {
        EnterpriseCacheSessionDAO enterpriseCacheSessionDAO = new EnterpriseCacheSessionDAO();
        //使用ehCacheManager
        enterpriseCacheSessionDAO.setCacheManager(getEhCacheManager());
        //設置session緩存的名字 默認爲 shiro-activeSessionCache
        enterpriseCacheSessionDAO.setActiveSessionsCacheName("shiro-activeSessionCache");
        //sessionId生成器
        enterpriseCacheSessionDAO.setSessionIdGenerator(sessionIdGenerator());
        return enterpriseCacheSessionDAO;
    }

     ShiroConfig的會話ID生成器:

    @Bean
    public SessionIdGenerator sessionIdGenerator() {
        return new JavaUuidSessionIdGenerator();
    }

     ShiroConfig的會話管理的Cookie:

 /**
     * 查詢定義sessionId的cookie,防止與SERVLET容器的衝突,默認JSESSIONID
     * 注意:這裏的cookie 不是上面的記住我 cookie 記住我需要一個cookie|session管理也需要自己的cookie
     */
    @Bean("sessionIdCookie")
    public SimpleCookie sessionIdCookie(){
        SimpleCookie simpleCookie = new SimpleCookie("sid");    //cookie的名稱
        simpleCookie.setHttpOnly(true); //設爲true後,只能通過http訪問,javascript無法訪問
        simpleCookie.setPath("/");
        simpleCookie.setMaxAge(-1);     //maxAge=-1表示瀏覽器關閉時失效此Cookie
        return simpleCookie;
    }

     Session監聽類:

package com.demo.config;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionListener;

import java.util.concurrent.atomic.AtomicInteger;

public class ShiroSessionListener implements SessionListener{
    /**
     * 統計在線人數,juc包下線程安全自增
     */
    private final AtomicInteger sessionCount = new AtomicInteger(0);
    /**
     * 會話創建時觸發
     */
    @Override
    public void onStart(Session session) {
        //會話創建,在線人數加一
        sessionCount.incrementAndGet();
    }
    /**
     * 退出會話時觸發
     */
    @Override
    public void onStop(Session session) {
        //會話退出,在線人數減一
        sessionCount.decrementAndGet();
    }

    /**
     * 會話過期時觸發
     */
    @Override
    public void onExpiration(Session session) {
        //會話過期,在線人數減一
        sessionCount.decrementAndGet();
    }
    /**
     * 獲取在線人數使用
     * @return
     */
    public AtomicInteger getSessionCount() {
        return sessionCount;
    }
}

     控制器:

	@RequestMapping("/userList.do")
	public String userList(Model model){
		//查詢所有的用戶信息並且顯示到頁面上
		Subject subject = SecurityUtils.getSubject();
		System.out.println("------是否通過認證:"+subject.isAuthenticated()+"------是否記住我:"+subject.isRemembered());
		List<User> list = userService.findAll();
		model.addAttribute("userList", list);
		model.addAttribute("count",shiroSessionListener.getSessionCount());
		return "userList";
	}

頁面獲取在線人數

當前在線人數:'[[${count}]]'

功能測試:

     訪問http://localhost:8080/userList.do登陸後,不關閉瀏覽器再次訪問改地址,是一樣可以訪問的,Web容器的Session一般默認30min才失效。
     本例中設置sessionManager.setGlobalSessionTimeout(10000); 也就是Shiro管理的session10秒後失效,所以登陸後頁面不作任何操作,10s後再訪問,session失效則需重新登陸。
     會話監聽器實現SessionListener接口,頁面能夠獲取統計的在線人數,

     參考文章
     springboot整合shiro-session管理(六)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章