Package org.apdplat.module.security.service

Source Code of org.apdplat.module.security.service.UserLoginListener

/**
*
* APDPlat - Application Product Development Platform
* Copyright (c) 2013, 杨尚川, yang-shangchuan@qq.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
*/

package org.apdplat.module.security.service;

import org.apdplat.module.monitor.model.UserLogin;
import org.apdplat.module.security.model.User;
import org.apdplat.module.system.service.PropertyHolder;
import org.apdplat.module.system.service.SystemListener;
import org.apdplat.platform.log.APDPlatLogger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apdplat.platform.log.APDPlatLoggerFactory;
import org.apdplat.platform.log.BufferLogCollector;
import org.apdplat.platform.service.ServiceFacade;
import org.apdplat.platform.util.SpringContextUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextImpl;


public class UserLoginListener implements HttpSessionAttributeListener,HttpSessionListener  {
    private static final APDPlatLogger LOG = APDPlatLoggerFactory.getAPDPlatLogger(UserLoginListener.class);

    private static Map<String,UserLogin> logs=new HashMap<>();

    private static Map<String,HttpSession> sessions=new HashMap<>();
    private static final boolean loginMonitor;
    static{
        loginMonitor=PropertyHolder.getBooleanProperty("monitor.login");
        if(loginMonitor){
            LOG.info("启用用户登录注销日志");
        }else{
            LOG.info("禁用用户登录注销日志");
        }
    }

    @Override
    public void attributeAdded(HttpSessionBindingEvent se) {
        if (se.getValue() instanceof SecurityContextImpl && loginMonitor) {
            User user=UserHolder.getCurrentLoginUser();
            if (null != user) {
                String sessioId=se.getSession().getId();
                LOG.info("用户 "+user.getUsername()+" 登录成功,会话ID:"+sessioId);

                if(logs.get(user.getUsername())==null){
                    LOG.info("开始记录用户 "+user.getUsername()+" 的登录日志");
                    String ip=UserHolder.getCurrentUserLoginIp();
                    UserLogin userLogin=new UserLogin();
                    userLogin.setAppName(SystemListener.getContextPath());
                    userLogin.setLoginIP(ip);
                    userLogin.setUserAgent(se.getSession().getAttribute("userAgent").toString());
                    userLogin.setLoginTime(new Date());
                    try {
                        userLogin.setServerIP(InetAddress.getLocalHost().getHostAddress());
                    } catch (UnknownHostException e) {
                        LOG.error("记录登录日志出错",e);
                    }
                    userLogin.setUsername(user.getUsername());
                    //保存用户登陆日志
                    BufferLogCollector.collect(userLogin);
                    logs.put(user.getUsername(), userLogin);
                }else{
                    LOG.info("用户 "+user.getUsername()+" 的登录日志已经被记录过,用户在未注销前又再次登录,忽略此登录");
                }
            }else{
                LOG.info("在登录的时候获得User失败");
            }
        }
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent se) {
        //不能从UserHolder中获取用户,因为会话已经销毁
        if (se.getValue() instanceof SecurityContextImpl && loginMonitor) {
            SecurityContext context=(SecurityContext)se.getValue();
            Authentication authentication=context.getAuthentication();
            if (authentication != null) {
                Object principal = authentication.getPrincipal();
                if (principal instanceof User) {
                    User user = (User) principal;
                    if (null != user) {
                        String sessioId=se.getSession().getId();
                        LOG.info("用户 "+user.getUsername()+" 注销成功,会话ID:"+sessioId);

                        UserLogin userLogin=logs.get(user.getUsername());
                        if(userLogin!=null){
                            LOG.info("开始记录用户 "+user.getUsername()+" 的注销日志");
                            userLogin.setLogoutTime(new Date());
                            userLogin.setOnlineTime(userLogin.getLogoutTime().getTime()-userLogin.getLoginTime().getTime());
                            //更新userLogin
                            ServiceFacade serviceFacade = SpringContextUtils.getBean("serviceFacadeForLog");
                            serviceFacade.update(userLogin);
                            logs.remove(user.getUsername());
                        }else{
                            LOG.info("无法记录用户 "+user.getUsername()+" 的注销日志,因为用户的登录日志不存在");
                        }
                    }else{
                        LOG.info("在注销的时候获得User失败");
                    }
                }
            }else{
                LOG.info("在注销的时候获得Authentication失败");
            }
        }
    }
   
    @Override
    public void attributeReplaced(HttpSessionBindingEvent se) {
    }

    @Override
    public void sessionCreated(HttpSessionEvent hse) {
        HttpSession session = hse.getSession();
        sessions.put(session.getId(), session);
        LOG.info("创建会话,ID:"+session.getId()+" ,当前共有会话:"+sessions.size());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent hse) {
        HttpSession session = hse.getSession();
        sessions.remove(session.getId());
        LOG.info("销毁会话,ID:"+session.getId()+" ,当前共有会话:"+sessions.size());
    }
   
    public static void forceAllUserOffline(){
        if(!loginMonitor){
            return;
        }
        int len=logs.size();
        if(len<1){
            return;
        }
       
        LOG.info("有 "+len+" 个用户还没有注销,强制所有用户退出");
        for(String username : logs.keySet()){
            UserLogin userLogin=logs.get(username);
            LOG.info("开始记录用户 "+username+" 的注销日志");
            userLogin.setLogoutTime(new Date());
            userLogin.setOnlineTime(userLogin.getLogoutTime().getTime()-userLogin.getLoginTime().getTime());
            //更新userLogin
            ServiceFacade serviceFacade = SpringContextUtils.getBean("serviceFacadeForLog");
            serviceFacade.update(userLogin);
            logs.remove(username);
        }
    }
}
TOP

Related Classes of org.apdplat.module.security.service.UserLoginListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.