cuilei
6 天以前 3a3b5bc665f526269bd622a70812bead173fbdf2
lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/system/controller/ThirdLoginController.java
@@ -9,6 +9,7 @@
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
@@ -16,6 +17,7 @@
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.RestUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.shiro.JwtToken;
import org.jeecg.config.thirdapp.ThirdAppConfig;
import org.jeecg.config.thirdapp.ThirdAppTypeItemVo;
import org.jeecg.modules.base.service.BaseCommonService;
@@ -64,6 +66,9 @@
   @Autowired
   private ThirdAppDingtalkServiceImpl thirdAppDingtalkService;
   /**token有效时间,目前现场要求企业微信有效时间*/
   public static final long EXPIRE_TIME = 30L * 24 * 60 * 60 * 1000;
   @RequestMapping("/render/{source}")
    public void render(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
        log.info("第三方登录进入render:" + source);
@@ -108,6 +113,9 @@
            String sysUserId = user.getSysUserId();
            SysUser sysUser = sysUserService.getById(sysUserId);
            String token = saveToken(sysUser);
            // 使用token进行Shiro登录
            JwtToken jwtToken = new JwtToken(token);
            SecurityUtils.getSubject().login(jwtToken); // 此行代码会触发Realm的认证方法,将用户信息存入Shiro的会话
             modelMap.addAttribute("token", token);
         }else{
            modelMap.addAttribute("token", "绑定手机号,"+""+uuid);
@@ -198,7 +206,7 @@
      String token = JwtUtil.sign(user.getUsername(), user.getPassword());
      redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
      // 设置超时时间
      redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
      redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, EXPIRE_TIME / 1000);
      return token;
   }
@@ -303,15 +311,17 @@
         // 企业的CorpID
         builder.append("?appid=").append(config.getClientId());
         // 授权后重定向的回调链接地址,请使用urlencode对链接进行处理
         String redirectUri = RestUtil.getBaseUrl() + "/sys/thirdLogin/oauth2/wechat_enterprise/callback";
         String redirectUri ="https://fastwoke.cn:8087/jeecg-boot/sys/thirdLogin/oauth2/wechat_enterprise/callback";
         builder.append("&redirect_uri=").append(URLEncoder.encode(redirectUri, "UTF-8"));
         // 返回类型,此时固定为:code
         builder.append("&response_type=code");
         // 应用授权作用域。
         // snsapi_base:静默授权,可获取成员的的基础信息(UserId与DeviceId);
         builder.append("&scope=snsapi_base");
         builder.append("&scope=snsapi_base");//静默授权
         //builder.append("&scope=snsapi_privateinfo"); // 手动授权作用域
         // 重定向后会带上state参数,长度不可超过128个字节
         builder.append("&state=").append(state);
         //builder.append("&agentid=").append(config.getAgentId()); // 补充AgentID(手动授权时需要)
         // 终端使用此参数判断是否需要带上身份信息
         builder.append("#wechat_redirect");
         url = builder.toString();
@@ -368,6 +378,10 @@
        SysUser loginUser;
        if (ThirdAppConfig.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
            log.info("【企业微信】OAuth2登录进入callback:code=" + code + ", state=" + state);
         if (code == null) {
            log.info("用户取消了企业微信授权");
            return "用户取消了授权";
         }
            loginUser = thirdAppWechatEnterpriseService.oauth2Login(code);
            if (loginUser == null) {
                return "登录失败";
@@ -394,12 +408,15 @@
         }
         String token = saveToken(loginUser);
         state += "/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
         // ============ 新增 Shiro 登录逻辑 ============
         JwtToken jwtToken = new JwtToken(token);
         SecurityUtils.getSubject().login(jwtToken);
         state += "/h5/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
         //update-begin---author:wangshuai ---date:20220613  for:[issues/I5BOUF]oauth2 钉钉无法登录------------
         state += "&thirdType=" + source;
         //state += "&thirdType=" + "wechat_enterprise";
         if (redirect != null && redirect.length() > 0) {
            state += "&redirect=" + redirect;
            state += "&" + redirect;
         }
         //update-end-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
@@ -418,4 +435,149 @@
        }
    }
   //企业微信适配手动授权接口调整
   ///**
   // * 企业微信/钉钉 OAuth2登录回调
   // *
   // * @param code
   // * @param state
   // * @param response
   // * @return
   // */
   //@ResponseBody
   //@GetMapping("/oauth2/{source}/callback")
   //public String oauth2LoginCallback(
   //      @PathVariable("source") String source,
   //      // 企业微信返回的code
   //      @RequestParam(value = "code", required = false) String code,
   //      // 钉钉返回的code
   //      @RequestParam(value = "authCode", required = false) String authCode,
   //      @RequestParam("state") String state,
   //      @RequestParam(value = "is_reject", required = false) String isReject,
   //      HttpServletResponse response) {
   //   SysUser loginUser;
   //   if (ThirdAppConfig.WECHAT_ENTERPRISE.equalsIgnoreCase(source)) {
   //      log.info("【企业微信】OAuth2登录进入callback:code=" + code + ", state=" + state);
   //      // 1. 判定用户拒绝授权的3种场景:
   //      //    - 场景1:is_reject=true(企业微信明确标识拒绝)
   //      //    - 场景2:code为null(未返回有效授权凭证)
   //      //    - 场景3:code存在但无效(调用API失败)
   //      boolean isUserReject = "true".equals(isReject) || code == null;
   //      if (isUserReject) {
   //         log.info("用户明确拒绝企业微信授权(is_reject={}, code={}", isReject, code);
   //         // 构造含error=access_denied的重定向地址,前端据此识别
   //         String errorRedirect = buildErrorRedirect(state, "access_denied");
   //         try {
   //            response.sendRedirect(errorRedirect);
   //            return "用户拒绝授权,已重定向";
   //         } catch (IOException e) {
   //            log.error("拒绝授权重定向失败", e);
   //            return "重定向失败";
   //         }
   //      }
   //
   //      // 2. 尝试用code获取用户信息(code存在但可能无效)
   //      loginUser = thirdAppWechatEnterpriseService.oauth2Login(code);
   //      if (loginUser == null) {
   //         log.info("企业微信授权失败(code无效)");
   //         String errorRedirect = buildErrorRedirect(state, "invalid_code");
   //         try {
   //            response.sendRedirect(errorRedirect);
   //            return "授权失败,已重定向";
   //         } catch (IOException e) {
   //            log.error("授权失败重定向失败", e);
   //            return "重定向失败";
   //         }
   //      }
   //      loginUser = thirdAppWechatEnterpriseService.oauth2Login(code);
   //      if (loginUser == null) {
   //         return "登录失败";
   //      }
   //   } else if (ThirdAppConfig.DINGTALK.equalsIgnoreCase(source)) {
   //      log.info("【钉钉】OAuth2登录进入callback:authCode=" + authCode + ", state=" + state);
   //      loginUser = thirdAppDingtalkService.oauth2Login(authCode);
   //      if (loginUser == null) {
   //         return "登录失败";
   //      }
   //   } else {
   //      return "不支持的source";
   //   }
   //   try {
   //
   //      //update-begin-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
   //      String redirect = "";
   //      if (state.indexOf("?") > 0) {
   //         String[] arr = state.split("\\?");
   //         state = arr[0];
   //         if(arr.length>1){
   //            redirect = arr[1];
   //         }
   //      }
   //
   //      String token = saveToken(loginUser);
   //      // ============ 新增 Shiro 登录逻辑 ============
   //      JwtToken jwtToken = new JwtToken(token);
   //      SecurityUtils.getSubject().login(jwtToken);
   //      state += "/h5/oauth2-app/login?oauth2LoginToken=" + URLEncoder.encode(token, "UTF-8");
   //      //update-begin---author:wangshuai ---date:20220613  for:[issues/I5BOUF]oauth2 钉钉无法登录------------
   //      state += "&thirdType=" + source;
   //      //state += "&thirdType=" + "wechat_enterprise";
   //      if (redirect != null && redirect.length() > 0) {
   //         state += "&" + redirect;
   //      }
   //      //update-end-author:taoyan date:2022-6-30 for: 工作流发送消息 点击消息链接跳转办理页面
   //
   //      //update-end---author:wangshuai ---date:20220613  for:[issues/I5BOUF]oauth2 钉钉无法登录------------
   //      log.info("OAuth2登录重定向地址: " + state);
   //      try {
   //         response.sendRedirect(state);
   //         return "ok";
   //      } catch (IOException e) {
   //         e.printStackTrace();
   //         return "重定向失败";
   //      }
   //   } catch (UnsupportedEncodingException e) {
   //      e.printStackTrace();
   //      return "解码失败";
   //   }
   //}
   //
   ///**
   // * 构造企业微信授权拒绝时的错误重定向地址
   // * 适配规则:state参数长度≤128字节,保留原始业务参数,附加error标识
   // */
   //private String buildErrorRedirect(String originalState, String errorCode) {
   //   // 1. 拆分原始state中的基础路径和业务参数(避免破坏原有state结构)
   //   String baseState = originalState;
   //   String businessParams = "";
   //   if (originalState.contains("?")) {
   //      String[] stateParts = originalState.split("\\?", 2); // 只拆分成两部分
   //      baseState = stateParts[0]; // 基础路径(如https://fastwoke.cn:8087)
   //      businessParams = stateParts[1]; // 原始业务参数(如redirect=xxx)
   //   }
   //
   //   // 2. 构造错误参数(error=xxx),并拼接原始业务参数
   //   StringBuilder errorParams = new StringBuilder();
   //   errorParams.append("error=").append(errorCode); // 核心错误标识
   //   if (!businessParams.isEmpty()) {
   //      errorParams.append("&").append(businessParams); // 附加原始业务参数
   //   }
   //
   //   // 3. 拼接完整的重定向地址(格式:baseState/h5/oauth2-app/login?errorParams)
   //   // 注意:企业微信要求重定向地址需与授权链接中的redirect_uri域名一致
   //   StringBuilder errorRedirect = new StringBuilder(baseState);
   //   errorRedirect.append("/h5/oauth2-app/login?").append(errorParams);
   //
   //   // 4. 校验state长度(企业微信限制≤128字节),超长时截断非关键参数
   //   String redirectUrl = errorRedirect.toString();
   //   if (redirectUrl.getBytes().length > 128) {
   //      log.warn("错误重定向地址超长,截断处理: {}", redirectUrl);
   //      // 只保留基础路径和error参数,舍弃其他业务参数
   //      redirectUrl = baseState + "/h5/oauth2-app/login?error=" + errorCode;
   //   }
   //
   //   log.info("企业微信拒绝授权重定向地址: {}", redirectUrl);
   //   return redirectUrl;
   //}
}