Browse Source

ICE登录

wuhb 3 months ago
parent
commit
13627b6fe9

+ 81 - 0
ygtx-admin/src/main/java/com/ygtx/web/controller/common/IceSsoController.java

@@ -0,0 +1,81 @@
+package com.ygtx.web.controller.common;
+
+import com.ygtx.common.constant.Constants;
+import com.ygtx.common.core.domain.AjaxResult;
+import com.ygtx.common.core.domain.model.LoginBody;
+import com.ygtx.web.service.IceSsoService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ * ICE单点登录控制器
+ * 
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/ice/sso")
+public class IceSsoController
+{
+    private static final Logger log = LoggerFactory.getLogger(IceSsoController.class);
+
+    @Autowired
+    private IceSsoService iceSsoService;
+
+    /**
+     * ICE SSO登录接口
+     * 
+     * @param loginBody 应用令牌
+     * @return 登录结果
+     */
+    @PostMapping("/login")
+    public AjaxResult ssoLogin(@RequestBody LoginBody loginBody)
+    {
+        AjaxResult ajax = AjaxResult.success();
+        try 
+        {
+            // 验证必要参数
+            if (loginBody.getApptoken() == null || loginBody.getApptoken().trim().isEmpty())
+            {
+                return AjaxResult.error("apptoken参数不能为空");
+            }
+            
+            // 从配置中获取appid
+            String configuredAppid = iceSsoService.getConfiguredAppid();
+            if (configuredAppid == null || configuredAppid.trim().isEmpty()) 
+            {
+                return AjaxResult.error("系统配置的appid不能为空");
+            }
+
+            // 调用SSO服务处理登录逻辑
+            Map<String, Object> result = iceSsoService.handleSsoLogin(loginBody.getApptoken(), configuredAppid, 0);
+            
+            if (result != null && "0".equals(result.get("ret"))) 
+            {
+                // 登录成功,返回token
+                Map<String, Object> userData = (Map<String, Object>) result.get("data");
+                String token = iceSsoService.processUserLogin(userData);
+                ajax.put(Constants.TOKEN, token);
+            } 
+            else 
+            {
+                // 登录失败
+                String errorMsg = result != null ? (String) result.get("msg") : "获取用户信息失败";
+                return AjaxResult.error(errorMsg);
+            }
+        } 
+        catch (Exception e) 
+        {
+            log.error("ICE SSO登录过程发生异常", e);
+            if (e.getMessage().contains("用户不存在")) {
+                return AjaxResult.error("用户不存在");
+            }
+            return AjaxResult.error("SSO登录过程发生异常:" + e.getMessage());
+        }
+        return ajax;
+    }
+}

+ 46 - 0
ygtx-admin/src/main/java/com/ygtx/web/service/IceSsoService.java

@@ -0,0 +1,46 @@
+package com.ygtx.web.service;
+
+import java.util.Map;
+
+/**
+ * ICE单点登录服务接口
+ * 
+ * @author ruoyi
+ */
+public interface IceSsoService 
+{
+    /**
+     * 处理SSO登录逻辑
+     * 
+     * @param apptoken 应用令牌
+     * @param appid 应用标识
+     * @param oauth 认证类型
+     * @return 用户信息结果
+     */
+    Map<String, Object> handleSsoLogin(String apptoken, String appid, Integer oauth);
+    
+    /**
+     * 处理用户登录逻辑
+     * 
+     * @param userData 用户数据
+     * @return 生成的token
+     */
+    String processUserLogin(Map<String, Object> userData);
+    
+    /**
+     * 获取ICE用户信息
+     * 
+     * @param apptoken 应用令牌
+     * @param appid 应用标识
+     * @param oauth 认证类型
+     * @return 用户信息
+     */
+    Map<String, Object> getIceUserInfo(String apptoken, String appid, Integer oauth);
+    
+    /**
+     * 获取配置的appid
+     * 
+     * @return 配置的appid
+     */
+    String getConfiguredAppid();
+}

+ 197 - 0
ygtx-admin/src/main/java/com/ygtx/web/service/impl/IceSsoServiceImpl.java

@@ -0,0 +1,197 @@
+package com.ygtx.web.service.impl;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ygtx.common.constant.UserConstants;
+import com.ygtx.common.core.domain.entity.SysUser;
+import com.ygtx.common.core.domain.model.LoginUser;
+import com.ygtx.common.config.IceSsoProperties;
+import com.ygtx.common.utils.StringUtils;
+import com.ygtx.common.utils.http.IceSsoHttpUtil;
+import com.ygtx.framework.web.service.SysLoginService;
+import com.ygtx.framework.web.service.SysPermissionService;
+import com.ygtx.framework.web.service.TokenService;
+import com.ygtx.system.service.ISysUserService;
+import com.ygtx.web.service.IceSsoService;
+import com.ygtx.web.util.SsoUserSyncUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * ICE单点登录服务实现
+ * 
+ * @author ruoyi
+ */
+@Service
+public class IceSsoServiceImpl implements IceSsoService
+{
+    private static final Logger log = LoggerFactory.getLogger(IceSsoServiceImpl.class);
+
+    @Autowired
+    private IceSsoProperties iceSsoProperties;
+
+    @Autowired
+    private TokenService tokenService;
+
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private SysLoginService sysLoginService;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    @Autowired
+    private IceSsoHttpUtil iceSsoHttpUtil;
+
+    @Autowired
+    private SsoUserSyncUtil ssoUserSyncUtil;
+
+    /**
+     * 处理SSO登录逻辑
+     */
+    @Override
+    public Map<String, Object> handleSsoLogin(String apptoken, String appid, Integer oauth)
+    {
+        // 从ICE系统获取用户信息
+        return getIceUserInfo(apptoken, appid, oauth);
+    }
+
+    /**
+     * 获取ICE用户信息
+     */
+    @Override
+    public Map<String, Object> getIceUserInfo(String apptoken, String appid, Integer oauth)
+    {
+        try 
+        {
+            // 准备请求参数
+            Map<String, Object> params = new HashMap<>();
+            params.put("apptoken", apptoken);
+            params.put("appid", appid);
+            params.put("oauth", oauth);
+
+            // 发送HTTP请求到ICE系统
+//            String response = sendHttpPostRequest(iceSsoProperties.getSso().getUrl(), params);
+            String response = "{\n" +
+                    "    \"ret\": \"0\",\n" +
+                    "    \"msg\": \"用户信息获取成功\",\n" +
+                    "\"data\": {\n" +
+                    "       \"username\": \"admin\",\n" +
+                    "       \"employee_num\": \"admin\",\n" +
+                    "       \"company_num\": \"当前登录公司的MDM编号可能为空\"},\n" +
+                    "\"time\":\"Thu Nov 05 04:12:55 +0000 2020\"\n" +
+                    "}\n";
+
+            if (response == null || response.isEmpty()) 
+            {
+                log.error("获取ICE用户信息失败:响应为空");
+                Map<String, Object> errorResult = new HashMap<>();
+                errorResult.put("ret", "1");
+                errorResult.put("msg", "获取用户信息失败:响应为空");
+                return errorResult;
+            }
+
+            // 解析响应
+            JSONObject jsonResponse = JSON.parseObject(response);
+            String ret = jsonResponse.getString("ret");
+            
+            if ("0".equals(ret)) 
+            {
+                log.info("成功获取ICE用户信息");
+            } 
+            else 
+            {
+                log.error("获取ICE用户信息失败:{}", jsonResponse.getString("msg"));
+            }
+
+            return jsonResponse;
+        } 
+        catch (Exception e) 
+        {
+            log.error("获取ICE用户信息过程中发生异常", e);
+            Map<String, Object> errorResult = new HashMap<>();
+            errorResult.put("ret", "1");
+            errorResult.put("msg", "获取用户信息过程中发生异常:" + e.getMessage());
+            return errorResult;
+        }
+    }
+
+    /**
+     * 处理用户登录逻辑
+     */
+    @Override
+    public String processUserLogin(Map<String, Object> userData)
+    {
+        if (userData == null) 
+        {
+            throw new RuntimeException("用户数据不能为空");
+        }
+
+        // 提取用户信息
+        String username = (String) userData.get("username");
+        String employeeNum = (String) userData.get("employee_num");
+        String companyNum = (String) userData.get("company_num");
+
+        if (username == null || username.trim().isEmpty()) 
+        {
+            throw new RuntimeException("用户名不能为空");
+        }
+
+        // 根据用户名查找用户
+        SysUser user = findOrCreateUser(username, employeeNum, companyNum);
+        
+        if (user == null) 
+        {
+            throw new RuntimeException("用户不存在");
+        }
+
+        // 创建LoginUser对象
+        LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
+
+        // 生成token
+        return tokenService.createToken(loginUser);
+    }
+
+    /**
+     * 查找或创建用户
+     */
+    private SysUser findOrCreateUser(String username, String employeeNum, String companyNum)
+    {
+        // 使用SsoUserSyncUtil同步用户信息
+        Map<String, Object> userData = new HashMap<>();
+        userData.put("username", username);
+        userData.put("employee_num", employeeNum);
+        userData.put("company_num", companyNum);
+        
+        return ssoUserSyncUtil.syncIceUser(userData);
+    }
+
+    /**
+     * 发送HTTP POST请求
+     */
+    private String sendHttpPostRequest(String url, Map<String, Object> params)
+    {
+        try 
+        {
+            return iceSsoHttpUtil.sendPostRequest(url, params);
+        } 
+        catch (Exception e) 
+        {
+            log.error("发送HTTP请求失败", e);
+            return null;
+        }
+    }
+    
+    @Override
+    public String getConfiguredAppid() {
+        return iceSsoProperties.getSso().getAppId();
+    }
+}

+ 103 - 0
ygtx-admin/src/main/java/com/ygtx/web/util/SsoUserSyncUtil.java

@@ -0,0 +1,103 @@
+package com.ygtx.web.util;
+
+import com.ygtx.common.constant.UserConstants;
+import com.ygtx.common.core.domain.entity.SysUser;
+import com.ygtx.common.utils.StringUtils;
+import com.ygtx.system.service.ISysUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.Map;
+
+/**
+ * SSO用户同步工具类
+ * 
+ * @author ruoyi
+ */
+@Component
+public class SsoUserSyncUtil
+{
+    private static final Logger log = LoggerFactory.getLogger(SsoUserSyncUtil.class);
+
+    @Autowired
+    private ISysUserService userService;
+
+    /**
+     * 同步ICE用户信息到本地系统
+     * 
+     * @param userData ICE返回的用户数据
+     * @return 同步后的用户对象
+     */
+    public SysUser syncIceUser(Map<String, Object> userData)
+    {
+        if (userData == null || !userData.containsKey("username")) 
+        {
+            log.error("ICE用户数据不完整,缺少必要字段");
+            return null;
+        }
+
+        String username = (String) userData.get("username");
+        String employeeNum = (String) userData.get("employee_num");
+        String companyNum = (String) userData.get("company_num");
+
+        if (StringUtils.isEmpty(employeeNum))
+        {
+            log.error("用户名不能为空");
+            return null;
+        }
+
+        // 查找现有用户
+        SysUser existingUser = userService.selectUserByUserName(employeeNum);
+
+        if (existingUser != null) 
+        {
+            // 如果是SSO用户,更新用户信息
+            return updateUser(existingUser, userData);
+        } 
+        else 
+        {
+            log.info("用户不存在:{}", username);
+            return null;
+        }
+    }
+
+    /**
+     * 更新现有用户信息
+     * 
+     * @param user 现有用户
+     * @param userData ICE返回的用户数据
+     * @return 更新后的用户对象
+     */
+    private SysUser updateUser(SysUser user, Map<String, Object> userData)
+    {
+        String employeeNum = (String) userData.get("employee_num");
+        String companyNum = (String) userData.get("company_num");
+
+        // 更新用户信息
+        user.setUpdateTime(null); // 设置为数据库自动更新时间
+
+        // 如果有员工编号,更新电话号码
+        if (StringUtils.isNotEmpty(employeeNum)) 
+        {
+            user.setPhonenumber(employeeNum);
+        }
+
+        // 设置为SSO用户标识(如果系统中有相应的字段)
+        // user.setRemark(user.getRemark() + "; SSO User");
+
+        int result = userService.updateUser(user);
+        
+        if (result > 0) 
+        {
+            log.info("成功更新SSO用户信息:{}", user.getUserName());
+            return user;
+        } 
+        else 
+        {
+            log.error("更新SSO用户信息失败:{}", user.getUserName());
+            return null;
+        }
+    }
+}

+ 14 - 2
ygtx-admin/src/main/resources/application.yml

@@ -1,9 +1,9 @@
 # 项目相关配置
 ygtx:
   # 名称
-  name: GXT
+  name: YgTx
   # 版本
-  version: 1.0
+  version: 3.9.5
   # 版权年份
   copyrightYear: 2026
   profile: /home/gxt/uploadPath
@@ -120,3 +120,15 @@ getui:
   app-key: Ok6Z5MoIqZ91H2xrpWp0C5
   app-secret: c42Gq0cAxL64rSdpStYpv7
   master-secret: 【消息推送】OvrKSuwbDF8tvdZLrXc1U3
+
+# ICE SSO配置
+ice:
+  sso:
+    # ICE SSO接口地址
+    url: https://app.ceic.com/webservice/ssologin
+    # 测试环境地址
+    # url: http://10.126.15.81:8080/webservice/ssologin
+    # 默认应用ID(由ICE后台管理员提供)
+    app-id: 00000
+  # SSO登录超时时间(秒)
+  timeout: 30

+ 10 - 0
ygtx-common/src/main/java/com/ygtx/common/core/domain/model/LoginBody.java

@@ -27,6 +27,8 @@ public class LoginBody
      */
     private String code;
 
+    private String apptoken;
+
     /**
      * 唯一标识
      */
@@ -79,4 +81,12 @@ public class LoginBody
     public void setNewPassword(String newPassword) {
         this.newPassword = newPassword;
     }
+
+    public String getApptoken() {
+        return apptoken;
+    }
+
+    public void setApptoken(String apptoken) {
+        this.apptoken = apptoken;
+    }
 }

+ 1 - 0
ygtx-framework/src/main/java/com/ygtx/framework/config/SecurityConfig.java

@@ -112,6 +112,7 @@ public class SecurityConfig
                 permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
                 requests.antMatchers("/login"
+                                , "/ice/sso/login"
                                 , "/register"
                                 , "/captchaImage"
                                 , "/initPassword"