Pārlūkot izejas kodu

feat:登录用户日志记录租户标识(更换逻辑)

韩帛霖 1 gadu atpakaļ
vecāks
revīzija
73d0764379

+ 48 - 0
zkqy-framework/src/main/java/com/zkqy/framework/manager/factory/AsyncFactory.java

@@ -80,6 +80,54 @@ public class AsyncFactory
         };
     }
 
+    // 重写
+    public static TimerTask recordLogininfor(final Long tenantId,final String username, final String status, final String message,
+                                             final Object... args)
+    {
+        final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
+        final String ip = IpUtils.getIpAddr();
+        return new TimerTask()
+        {
+            @Override
+            public void run()
+            {
+                String address = AddressUtils.getRealAddressByIP(ip);
+                StringBuilder s = new StringBuilder();
+                s.append(LogUtils.getBlock(ip));
+                s.append(address);
+                s.append(LogUtils.getBlock(username));
+                s.append(LogUtils.getBlock(status));
+                s.append(LogUtils.getBlock(message));
+                // 打印信息到日志
+                sys_user_logger.info(s.toString(), args);
+                // 获取客户端操作系统
+                String os = userAgent.getOperatingSystem().getName();
+                // 获取客户端浏览器
+                String browser = userAgent.getBrowser().getName();
+                // 封装对象
+                SysLogininfor logininfor = new SysLogininfor();
+                logininfor.setUserName(username);
+                logininfor.setIpaddr(ip);
+                logininfor.setLoginLocation(address);
+                logininfor.setBrowser(browser);
+                logininfor.setOs(os);
+                logininfor.setMsg(message);
+                // 增加租户标识
+                logininfor.setTenantId(tenantId);
+                // 日志状态
+                if (StringUtils.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER))
+                {
+                    logininfor.setStatus(Constants.SUCCESS);
+                }
+                else if (Constants.LOGIN_FAIL.equals(status))
+                {
+                    logininfor.setStatus(Constants.FAIL);
+                }
+                // 插入数据
+                SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
+            }
+        };
+    }
     /**
      * 操作日志记录
      * 

+ 8 - 9
zkqy-framework/src/main/java/com/zkqy/framework/security/handle/LogoutSuccessHandlerImpl.java

@@ -4,6 +4,7 @@ import java.io.IOException;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.security.core.Authentication;
@@ -20,32 +21,30 @@ import com.zkqy.framework.web.service.TokenService;
 
 /**
  * 自定义退出处理类 返回成功
- * 
+ *
  * @author ruoyi
  */
 @Configuration
-public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
-{
+public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler {
     @Autowired
     private TokenService tokenService;
 
     /**
      * 退出处理
-     * 
+     *
      * @return
      */
     @Override
     public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
-            throws IOException, ServletException
-    {
+            throws IOException, ServletException {
         LoginUser loginUser = tokenService.getLoginUser(request);
-        if (StringUtils.isNotNull(loginUser))
-        {
+        if (StringUtils.isNotNull(loginUser)) {
             String userName = loginUser.getUsername();
             // 删除用户缓存记录
             tokenService.delLoginUser(loginUser.getToken());
+            Long tenantId = loginUser.getTenantId() == null ? 0L : loginUser.getTenantId();
             // 记录用户退出日志
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(tenantId, userName, Constants.LOGOUT, "退出成功"));
         }
         ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功")));
     }

+ 41 - 51
zkqy-framework/src/main/java/com/zkqy/framework/web/service/SysLoginService.java

@@ -40,12 +40,11 @@ import java.time.ZoneOffset;
 
 /**
  * 登录校验方法
- * 
+ *
  * @author ruoyi
  */
 @Component
-public class SysLoginService
-{
+public class SysLoginService {
     @Autowired
     private TokenService tokenService;
 
@@ -54,7 +53,7 @@ public class SysLoginService
 
     @Autowired
     private RedisCache redisCache;
-    
+
     @Autowired
     private ISysUserService userService;
 
@@ -66,15 +65,14 @@ public class SysLoginService
 
     /**
      * 登录验证
-     * 
+     *
      * @param username 用户名
      * @param password 密码
-     * @param code 验证码
-     * @param uuid 唯一标识
+     * @param code     验证码
+     * @param uuid     唯一标识
      * @return 结果
      */
-    public String login(String username, String password, String code, String uuid)
-    {
+    public String login(String username, String password, String code, String uuid) {
         //验证码校验
         validateCaptcha(username, code, uuid);
         //登录前置校验
@@ -82,32 +80,33 @@ public class SysLoginService
 
         // 用户验证
         Authentication authentication = null;
-        try
-        {
+        try {
             UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
             AuthenticationContextHolder.setContext(authenticationToken);
             // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
             authentication = authenticationManager.authenticate(authenticationToken);
-        }
-        catch (Exception e)
-        {
-            if (e instanceof BadCredentialsException)
-            {
+        } catch (Exception e) {
+            if (e instanceof BadCredentialsException) {
                 AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                 throw new UserPasswordNotMatchException();
-            }
-            else
-            {
+            } else {
                 AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                 throw new ServiceException(e.getMessage());
             }
-        }
-        finally
-        {
+        } finally {
             AuthenticationContextHolder.clearContext();
         }
-        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
         LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+        Long tenantId;
+        try {
+            tenantId = loginUser.getTenantId();
+            if (tenantId == null) {
+                tenantId = 0L;// 0L 表示当前是admin(租户信息表id自增「自增id不会从0开始」)
+            }
+        } catch (Exception exception) {
+            tenantId = 0L;  // 0L 表示当前是admin(租户信息表id自增「自增id不会从0开始」)
+        }
+        AsyncManager.me().execute(AsyncFactory.recordLogininfor(tenantId, username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
         recordLoginInfo(loginUser.getUserId());
         // 生成token
         return tokenService.createToken(loginUser);
@@ -115,27 +114,23 @@ public class SysLoginService
 
     /**
      * 校验验证码
-     * 
+     *
      * @param username 用户名
-     * @param code 验证码
-     * @param uuid 唯一标识
+     * @param code     验证码
+     * @param uuid     唯一标识
      * @return 结果
      */
-    public void validateCaptcha(String username, String code, String uuid)
-    {
+    public void validateCaptcha(String username, String code, String uuid) {
         boolean captchaEnabled = configService.selectCaptchaEnabled();
-        if (captchaEnabled)
-        {
+        if (captchaEnabled) {
             String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
             String captcha = redisCache.getCacheObject(verifyKey);
             redisCache.deleteObject(verifyKey);
-            if (captcha == null)
-            {
+            if (captcha == null) {
                 AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
                 throw new CaptchaExpireException();
             }
-            if (!code.equalsIgnoreCase(captcha))
-            {
+            if (!code.equalsIgnoreCase(captcha)) {
                 AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
                 throw new CaptchaException();
             }
@@ -144,35 +139,31 @@ public class SysLoginService
 
     /**
      * 登录前置校验
+     *
      * @param username 用户名
      * @param password 用户密码
      */
-    public void loginPreCheck(String username, String password)
-    {
+    public void loginPreCheck(String username, String password) {
         // 用户名或密码为空 错误
-        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
-        {
+        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
             throw new UserNotExistsException();
         }
         // 密码如果不在指定范围内 错误
         if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
-                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
-        {
+                || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
             throw new UserPasswordNotMatchException();
         }
         // 用户名不在指定范围内 错误
         if (username.length() < UserConstants.USERNAME_MIN_LENGTH
-                || username.length() > UserConstants.USERNAME_MAX_LENGTH)
-        {
+                || username.length() > UserConstants.USERNAME_MAX_LENGTH) {
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
             throw new UserPasswordNotMatchException();
         }
         // IP黑名单校验
         String blackStr = configService.selectConfigByKey("sys.login.blackIPList");
-        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
-        {
+        if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr())) {
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("login.blocked")));
             throw new BlackListException();
         }
@@ -183,8 +174,7 @@ public class SysLoginService
      *
      * @param userId 用户ID
      */
-    public void recordLoginInfo(Long userId)
-    {
+    public void recordLoginInfo(Long userId) {
         SysUser sysUser = new SysUser();
         sysUser.setUserId(userId);
         sysUser.setLoginIp(IpUtils.getIpAddr());
@@ -195,24 +185,24 @@ public class SysLoginService
     public String checkTenantExpirationTime(String username) {
         SysUser user = userService.selectUserByUserName(username);
         //拿到当前登录用户
-        if(!user.getUserName().equals("admin")){
+        if (!user.getUserName().equals("admin")) {
             //根据租户id查询租户信息
             SysTenant sysTenant = sysTenantService.selectSysTenantByTenantId(user.getTenantId());
-            if(sysTenant.getTenantExpirationTime()==null||sysTenant.getTenantExpirationTime().isEmpty()){
+            if (sysTenant.getTenantExpirationTime() == null || sysTenant.getTenantExpirationTime().isEmpty()) {
                 return "该用户租户信息并未激活";
             }
             SymmetricCrypto symmetricCrypto = new SymmetricCrypto(SymmetricAlgorithm.DES, "sgEsnN6QWq8W7j5H01020304".getBytes());
             //当前时间
-            LocalDateTime now=LocalDateTime.now();
+            LocalDateTime now = LocalDateTime.now();
             long nowSecond = now.toEpochSecond(ZoneOffset.ofHours(8));
             //到期时间
             String LastActiveTimeStr = symmetricCrypto.decryptStr(sysTenant.getTenantExpirationTime(), CharsetUtil.CHARSET_UTF_8);
             LocalDateTime LastActiveDateTime = DateUtils.toLocalDateTime(LastActiveTimeStr, "yyyy-MM-dd HH:mm:ss");
             long expirationTimeSecond = LastActiveDateTime.toEpochSecond(ZoneOffset.ofHours(8));
             //计算时间戳
-            long difference=expirationTimeSecond-nowSecond; //相差的时间数 后边减前边
+            long difference = expirationTimeSecond - nowSecond; //相差的时间数 后边减前边
             //如果是负数证明已经过期了
-            if(difference<0){
+            if (difference < 0) {
                 return "该用户租户信息已过期";
             }
         }

+ 0 - 7
zkqy-system/src/main/java/com/zkqy/system/service/impl/SysLogininforServiceImpl.java

@@ -27,13 +27,6 @@ public class SysLogininforServiceImpl implements ISysLogininforService {
      */
     @Override
     public void insertLogininfor(SysLogininfor logininfor) {
-        Long tenantId;
-        try {
-            tenantId = SecurityUtils.getTenantId();
-        } catch (Exception exception) {
-            tenantId = 0L;  // 0L 表示当前是admin(租户信息表id自增「自增id不会从0开始」)
-        }
-        logininfor.setTenantId(tenantId);
         logininforMapper.insertLogininfor(logininfor);
     }