shiro實現(xiàn)限制單用戶多地登錄

賬號在同一時間只能在一處登錄(非單點登錄)實現(xiàn)方式大致三種:

  1. session隔離
  2. 數(shù)據(jù)庫記錄
  3. shiro實現(xiàn)

shiro實現(xiàn)方式
1.shiro配置

<bean id="myRealm" class="com.sys.shiro.MyRealm" />

<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"></bean>
    
<bean id="sessionManager"
        class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="globalSessionTimeout" value="1800000" />
        <property name="deleteInvalidSessions" value="true" />
        <property name="sessionValidationSchedulerEnabled" value="true" />
        <property name="sessionValidationInterval" value="1800000" />
        <property name="sessionIdCookie" ref="sessionIdCookie" />
        <property name="sessionDAO" ref="sessionDAO"/>
    </bean>


    <!-- Shiro默認會使用Servlet容器的Session,可通過sessionMode屬性來指定使用Shiro原生Session -->
    <!-- 即<property name="sessionMode" value="native"/>,詳細說明見官方文檔 -->
    <!-- 這里主要是設(shè)置自定義的單Realm應(yīng)用,若有多個Realm,可使用'realms'屬性代替 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="cacheManager" ref="shiroCacheManager" />
        <property name="realm" ref="myRealm" />
        <property name="sessionManager" ref="sessionManager" />
    </bean>

2.代碼

  @Autowired  
  private SessionDAO sessionDAO; 

    /**
     * 實現(xiàn)用戶登錄
     * @param username
     * @param password
     * @return
     */
    @RequestMapping(value = "doLogin")
    public ModelAndView Login(String username, String password) {
        ModelAndView mav = new ModelAndView();
        User user = loginService.getUser(username);
        if (user == null) {
            mav.setViewName("login");
            mav.addObject("msg", "用戶不存在");
            return mav;
        }
        if (!user.getPassword().equals(password)) {
            mav.setViewName("login");
            mav.addObject("msg", "賬號密碼錯誤");
            return mav;
        }

        Collection<Session> sessions = sessionDao.getActiveSessions();
        for (Session session : sessions) {
            System.out.println("登錄用戶" + session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY));
           
            //shiro session可以拿到已經(jīng)登陸的username
            System.out.println("登錄用戶" + session.getAttribute("userName"));

        if (username.equals(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY))) {
                mav.setViewName("login");
                mav.addObject("msg", "該用戶已登錄");
                // session.setTimeout(0);  //這里就把session清除
                sessionDAO.delete(session); //session清除西土,  
                return mav;
            }
        }


        // 登錄后存放進shiro token
        UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user.getPassword());
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.login(token);
        //httpSession
        currentUser.getSession().setAttribute("loginName",username);
        //shiro Session
        currentUser.getSession(true).setAttribute("userName",username);

        // 登錄成功后會跳轉(zhuǎn)到successUrl配置的鏈接,不用管下面返回的鏈接祖很。
        mav.setViewName("redirect:home");
        return mav;
    }

3.結(jié)束!


  • shiro獲取所有在線用戶方法
//apache shiro獲取所有在線用戶:
Collection sessions = sessionDAO.getActiveSessions();
for(Session session:sessions){
    System.out.println("登錄ip:"+session.getHost());
    System.out.println("登錄用戶"+session.getAttribute(DefaultWebContext.PRINCIPALS_SESSION_KEY));
    System.out.println("最后操作日期:"+session.getLastAccessTime());
}

  • session移除另外一種方式
/*
 *在 LocalAuthorizingRealm 中,用戶登錄進行認證之前候醒,先將該用戶的其他session移除
 */
@Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String userName = (String)authenticationToken.getPrincipal();
 
        //處理session
        DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
        DefaultWebSessionManager sessionManager = (DefaultWebSessionManager)securityManager.getSessionManager();
        Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();//獲取當前已登錄的用戶session列表
        for(Session session:sessions){
            //清除該用戶以前登錄時保存的session
            if(userName.equals(String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)))) {
                sessionManager.getSessionDAO().delete(session);
            }
        }
 
        String pwd = null;
        return new SimpleAuthenticationInfo(userName,pwd,getName());
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市杂瘸,隨后出現(xiàn)的幾起案子倒淫,更是在濱河造成了極大的恐慌,老刑警劉巖败玉,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件敌土,死亡現(xiàn)場離奇詭異镜硕,居然都是意外死亡,警方通過查閱死者的電腦和手機返干,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門兴枯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人矩欠,你說我怎么就攤上這事财剖。” “怎么了癌淮?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵躺坟,是天一觀的道長。 經(jīng)常有香客問我乳蓄,道長咪橙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任栓袖,我火速辦了婚禮匣摘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘裹刮。我一直安慰自己音榜,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布捧弃。 她就那樣靜靜地躺著赠叼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪违霞。 梳的紋絲不亂的頭發(fā)上嘴办,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音买鸽,去河邊找鬼涧郊。 笑死,一個胖子當著我的面吹牛眼五,可吹牛的內(nèi)容都是我干的妆艘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼看幼,長吁一口氣:“原來是場噩夢啊……” “哼批旺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起诵姜,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤汽煮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體暇赤,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡心例,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了翎卓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片契邀。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡摆寄,死狀恐怖失暴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情微饥,我是刑警寧澤逗扒,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站欠橘,受9級特大地震影響矩肩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肃续,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一黍檩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧始锚,春花似錦刽酱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至姐呐,卻和暖如春殿怜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背曙砂。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工头谜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鸠澈。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓语盈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親瑟捣。 傳聞我的和親對象是個殘疾皇子湃累,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容