Просмотр исходного кода

重写session和session工厂,增加session列表管理

shuzheng 9 лет назад
Родитель
Сommit
e8ed66af80

+ 57 - 0
zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/shiro/UpmsSession.java

@@ -0,0 +1,57 @@
+package com.zheng.upms.server.shiro;
+
+import org.apache.shiro.session.mgt.SimpleSession;
+
+/**
+ * 重写session
+ * Created by shuzheng on 2017/2/27.
+ */
+public class UpmsSession extends SimpleSession {
+
+    public static enum OnlineStatus {
+        on_line("在线"), hidden("隐身"), force_logout("强制退出");
+        private final String info;
+
+        private OnlineStatus(String info) {
+            this.info = info;
+        }
+
+        public String getInfo() {
+            return info;
+        }
+    }
+
+    // 用户浏览器类型
+    private String userAgent;
+
+    // 在线状态
+    private OnlineStatus status = OnlineStatus.on_line;
+
+    // 用户登录时系统IP
+    private String systemHost;
+
+    public String getUserAgent() {
+        return userAgent;
+    }
+
+    public void setUserAgent(String userAgent) {
+        this.userAgent = userAgent;
+    }
+
+    public OnlineStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(OnlineStatus status) {
+        this.status = status;
+    }
+
+    public String getSystemHost() {
+        return systemHost;
+    }
+
+    public void setSystemHost(String systemHost) {
+        this.systemHost = systemHost;
+    }
+
+}

+ 34 - 10
zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/shiro/SessionRedisDao.java → zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/shiro/UpmsSessionDao.java

@@ -1,6 +1,5 @@
 package com.zheng.upms.server.shiro;
 
-import com.zheng.common.util.CookieUtil;
 import com.zheng.common.util.RedisUtil;
 import org.apache.shiro.session.Session;
 import org.apache.shiro.session.mgt.SimpleSession;
@@ -10,17 +9,22 @@ import org.slf4j.LoggerFactory;
 import redis.clients.jedis.Jedis;
 
 import java.io.*;
+import java.util.List;
 import java.util.Set;
 
 /**
  * 基于redis的sessionDao,缓存共享session
  * Created by shuzheng on 2017/2/23.
  */
-public class SessionRedisDao extends EnterpriseCacheSessionDAO {
+public class UpmsSessionDao extends EnterpriseCacheSessionDAO {
 
-    private static Logger _log = LoggerFactory.getLogger(SessionRedisDao.class);
-    // 全局会话key
+    private static Logger _log = LoggerFactory.getLogger(UpmsSessionDao.class);
+    // 全局会话cookie的key
     private final static String ZHENG_UPMS_SERVER_SESSION_ID = "zheng-upms-server-session-id";
+    // 全局会话redis的key
+    private final static String ZHENG_UPMS_SHIRO_SESSION_ID = "zheng-upms-shiro-session-id";
+    // 全局会话redis的id列表key
+    private final static String ZHENG_UPMS_SHIRO_SESSION_IDS = "zheng-upms-shiro-session-ids";
     // token key
     private final static String ZHENG_UPMS_SERVER_TOKEN = "zheng-upms-server-token";
     // 局部会话key
@@ -31,8 +35,12 @@ public class SessionRedisDao extends EnterpriseCacheSessionDAO {
     @Override
     protected Serializable doCreate(Session session) {
         Serializable sessionId = super.doCreate(session);
-        RedisUtil.set(sessionToByte("shiro-sessionId-" + sessionId), sessionToByte(session));
-        _log.debug("[SessionRedisDao]创建session: sessionId={}", session.getId());
+        RedisUtil.set(sessionToByte(ZHENG_UPMS_SHIRO_SESSION_ID + "_" + sessionId), sessionToByte(session));
+        _log.debug("[UpmsSessionDao]创建session: sessionId={}", session.getId());
+        // 维护会话id列表,提供会话分页管理
+        Jedis jedis = RedisUtil.getJedis();
+        jedis.lpush(ZHENG_UPMS_SHIRO_SESSION_IDS, sessionId.toString());
+        jedis.close();
         return sessionId;
     }
 
@@ -44,7 +52,7 @@ public class SessionRedisDao extends EnterpriseCacheSessionDAO {
             byte[] bytes = RedisUtil.get(sessionId.toString().getBytes());
             if(null != bytes && bytes.length > 0){
                 session = (Session) byteToSession(bytes);
-                _log.debug("[SessionRedisDao]redis中获取session: sessionId={}", session.getId());
+                _log.debug("[UpmsSessionDao]redis中获取session: sessionId={}", session.getId());
             }
         }
         return session;
@@ -55,7 +63,7 @@ public class SessionRedisDao extends EnterpriseCacheSessionDAO {
         // 更新session的最后一次访问时间
         super.doUpdate(session);
         RedisUtil.set(session.getId().toString().getBytes(), sessionToByte(session));
-        _log.debug("[SessionRedisDao]redis中更新session: sessionId={}", session.getId());
+        _log.debug("[UpmsSessionDao]redis中更新session: sessionId={}", session.getId());
     }
 
     @Override
@@ -80,8 +88,24 @@ public class SessionRedisDao extends EnterpriseCacheSessionDAO {
 
         // 删除session
         super.doDelete(session);
-        RedisUtil.remove(session.getId().toString().getBytes());
-        _log.debug("[SessionRedisDao]redis中删除session: sessionId={}", session.getId());
+        RedisUtil.remove(sessionToByte(ZHENG_UPMS_SHIRO_SESSION_ID + "_" + serverSessionId));
+        _log.debug("[UpmsSessionDao]redis中删除session: sessionId={}", session.getId());
+
+        // 维护会话id列表,提供会话分页管理
+        jedis = RedisUtil.getJedis();
+        jedis.lrem(ZHENG_UPMS_SHIRO_SESSION_IDS, 1, serverSessionId);
+        jedis.close();
+    }
+
+    /**
+     * 获取会话列表
+     * @param page
+     * @param size
+     * @return
+     */
+    List<Session> getActiveSessions(int page, int size) {
+        // TODO
+        return null;
     }
 
     // 把Object对象转化为byte保存到redis中

+ 56 - 0
zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/shiro/UpmsSessionFactory.java

@@ -0,0 +1,56 @@
+package com.zheng.upms.server.shiro;
+
+import org.apache.shiro.session.Session;
+import org.apache.shiro.session.mgt.SessionContext;
+import org.apache.shiro.session.mgt.SessionFactory;
+import org.apache.shiro.web.session.mgt.WebSessionContext;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * session工厂
+ * Created by shuzheng on 2017/2/27.
+ */
+public class UpmsSessionFactory implements SessionFactory {
+
+    @Override
+    public Session createSession(SessionContext sessionContext) {
+        UpmsSession session = new UpmsSession();
+        if (sessionContext != null && sessionContext instanceof WebSessionContext) {
+            WebSessionContext webSessionContext = (WebSessionContext) sessionContext;
+            HttpServletRequest request = (HttpServletRequest) webSessionContext.getServletRequest();
+            if (request != null) {
+                session.setHost(request.getRemoteAddr());
+                session.setUserAgent(request.getHeader("User-Agent"));
+                session.setSystemHost(request.getLocalAddr() + ":" + request.getLocalPort());
+            }
+        }
+        return session;
+    }
+
+    /**
+     * 获取ip工具类,除了getRemoteAddr,其他ip均可伪造
+     * @param request
+     * @return
+     */
+    public String getIpAddr(HttpServletRequest request) {
+        String ip = request.getHeader("Cdn-Src-Ip");    // 网宿cdn的真实ip
+        if (ip == null || ip.length() == 0 || " unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("HTTP_CLIENT_IP");   // 蓝讯cdn的真实ip
+        }
+        if (ip == null || ip.length() == 0 || " unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Forwarded-For");  // 获取代理ip
+        }
+        if (ip == null || ip.length() == 0 || " unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP"); // 获取代理ip
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP"); // 获取代理ip
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr(); // 获取真实ip
+        }
+        return ip;
+    }
+
+}

+ 3 - 4
zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/shiro/listener/ShiroSessionListener.java → zheng-upms/zheng-upms-server/src/main/java/com/zheng/upms/server/shiro/UpmsSessionListener.java

@@ -1,6 +1,5 @@
-package com.zheng.upms.server.shiro.listener;
+package com.zheng.upms.server.shiro;
 
-import com.zheng.upms.server.controller.manage.UpmsOrganizationController;
 import org.apache.shiro.session.Session;
 import org.apache.shiro.session.SessionListener;
 import org.slf4j.Logger;
@@ -9,9 +8,9 @@ import org.slf4j.LoggerFactory;
 /**
  * Created by shuzheng on 2017/2/12.
  */
-public class ShiroSessionListener implements SessionListener {
+public class UpmsSessionListener implements SessionListener {
 
-    private static Logger _log = LoggerFactory.getLogger(ShiroSessionListener.class);
+    private static Logger _log = LoggerFactory.getLogger(UpmsSessionListener.class);
 
     @Override
     public void onStart(Session session) {

+ 6 - 2
zheng-upms/zheng-upms-server/src/main/resources/applicationContext-shiro.xml

@@ -58,6 +58,7 @@
         <property name="sessionListeners">
             <list><ref bean="sessionListener"/></list>
         </property>
+        <property name="sessionFactory" ref="sessionFactory"/>
     </bean>
 
     <!-- 会话验证调度器 -->
@@ -68,7 +69,7 @@
     </bean>
 
     <!-- 会话DAO,可重写,持久化session -->
-    <bean id="sessionDAO" class="com.zheng.upms.server.shiro.SessionRedisDao"/>
+    <bean id="sessionDAO" class="com.zheng.upms.server.shiro.UpmsSessionDao"/>
 
     <!-- 会话Cookie模板 -->
     <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
@@ -81,7 +82,10 @@
     </bean>
 
     <!-- 会话监听器 -->
-    <bean id="sessionListener" class="com.zheng.upms.server.shiro.listener.ShiroSessionListener"/>
+    <bean id="sessionListener" class="com.zheng.upms.server.shiro.UpmsSessionListener"/>
+
+    <!-- session工厂 -->
+    <bean id="sessionFactory" class="com.zheng.upms.server.shiro.UpmsSessionFactory"/>
 
     <!-- rememberMe管理器 -->
     <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">