first commit
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
package io.v.nutz.wechat;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import io.v.nutz.base.result.Result;
|
||||
import io.v.nutz.base.utils.LoginUtil;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.sys.services.SysUserService;
|
||||
import io.v.nutz.task.model.TaskToken;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import io.v.nutz.web.commons.shiro.exception.CaptchaEmptyException;
|
||||
import io.v.nutz.web.commons.shiro.exception.CaptchaIncorrectException;
|
||||
import io.v.nutz.web.commons.shiro.token.PlatformCaptchaToken;
|
||||
import io.v.nutz.web.commons.slog.annotation.SLog;
|
||||
import lombok.extern.log4j.Log4j;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.AuthenticationException;
|
||||
import org.apache.shiro.authc.LockedAccountException;
|
||||
import org.apache.shiro.authc.UnknownAccountException;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.eclipse.jetty.server.session.Session;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.http.Http;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.json.Json;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.Serializable;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.MessageDigest;
|
||||
import java.sql.Struct;
|
||||
|
||||
/*
|
||||
"/dd3s/mobile/union"是针对于南京理工大学特定的
|
||||
因为移动端获取工号和其他学校不一样
|
||||
原理是移动端访问/dd3s/mobile/union/getUserInfo,被微信认证集成平台反向代理拦截,拦截后获取到工号再通过转发的方式给我们
|
||||
工号信息就放在request头部信息中
|
||||
因为第三方公司说路径最好加个特殊标识,所以加了dd3s
|
||||
*/
|
||||
@IocBean
|
||||
@Slf4j
|
||||
@At({"/weChat/union", "/dd3s/mobile/union"})
|
||||
public class WeChatLoginController {
|
||||
|
||||
private static final String seckey = "zhghDap863vth6k1t";
|
||||
private static final String taskType = "企业微信";
|
||||
private static String APPID = "wxf2f6f120053cf5eb";
|
||||
private static String accessTokenUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s";
|
||||
private static String oauthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private SysUserService sysUserService;
|
||||
@Inject
|
||||
private LoginUtil loginUtil;
|
||||
|
||||
public static String aesDecodeAccountInfo(String key, String hexAccount) throws Exception {
|
||||
MessageDigest md5Encoder = MessageDigest.getInstance("MD5");
|
||||
byte[] accountSrcBytes = Hex.decodeHex(hexAccount.toCharArray());
|
||||
byte[] md5Key = md5Encoder.digest(key.getBytes());
|
||||
md5Encoder.reset();
|
||||
md5Encoder.update(md5Key);
|
||||
md5Encoder.update(key.getBytes());
|
||||
byte[] iv = md5Encoder.digest();
|
||||
SecretKey secretKey = new SecretKeySpec(md5Key, "AES");
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
|
||||
byte[] accountDstBytes = cipher.doFinal(accountSrcBytes);
|
||||
return new String(accountDstBytes);
|
||||
}
|
||||
|
||||
@At("/login")
|
||||
@Ok("re")
|
||||
public String login() {
|
||||
String redirect_url = Globals.AppDomain + "/dd3s/mobile/union/getUserInfo";
|
||||
return ">>:" + redirect_url;
|
||||
}
|
||||
|
||||
@At("/getUserInfo")
|
||||
@Ok("re")
|
||||
public String getUserInfo(HttpServletRequest request, HttpSession session) throws Exception {
|
||||
try {
|
||||
String encryptUser = request.getHeader("EncryptUser");
|
||||
log.debug("encryptUser为:" + encryptUser);
|
||||
String resultStr = aesDecodeAccountInfo(seckey, encryptUser);
|
||||
String loginName = resultStr.split(",")[0];
|
||||
log.debug("企业微信获取的工号为:" + loginName);
|
||||
return ">>:" + Globals.AppDomain + "/dd3s/mobile/union/toLogin?loginName=" + loginName;
|
||||
} catch (Exception e) {
|
||||
log.error("企业微信登录失败:" + e.getMessage());
|
||||
request.setAttribute("errMsg", "系统中没有此用户");
|
||||
return ">>:" + Globals.AppDomain + "/platform/home/UnknownAccountError";
|
||||
}
|
||||
}
|
||||
|
||||
@At("/toLogin")
|
||||
@Ok("re")
|
||||
public String toLogin(String loginName, HttpServletRequest request, HttpSession session) {
|
||||
try {
|
||||
loginUtil.doLogin(loginName, request, session, LoginUtil.LoginOrigin.QI_YE_WEI_XIN);
|
||||
return ">>:" + Globals.AppDomain + "/mobile/index";
|
||||
} catch (LockedAccountException e) {
|
||||
log.error("企业微信登录失败:" + e.getMessage());
|
||||
request.setAttribute("errMsg", "帐号被锁定,请5分钟后再试");
|
||||
return ">>:" + Globals.AppDomain + "/platform/home/LockedAccountError";
|
||||
} catch (UnknownAccountException e) {
|
||||
log.error("企业微信登录失败:" + e.getMessage());
|
||||
request.setAttribute("errMsg", "系统中没有此用户");
|
||||
return ">>:" + Globals.AppDomain + "/platform/home/UnknownAccountError";
|
||||
} catch (Exception e) {
|
||||
log.error("企业微信登录失败:" + e.getMessage());
|
||||
request.setAttribute("errMsg", "用户名或密码错误");
|
||||
return ">>:" + Globals.AppDomain + "/platform/home/500";
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("re")
|
||||
public String getCode(@Param("code") String code, HttpSession session) {
|
||||
String token = getAccessToken();
|
||||
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" + token + "&code=" + code;
|
||||
NutMap resMap = Json.fromJson(NutMap.class, HttpUtil.get(url));
|
||||
String loginname = resMap.getString("UserId");
|
||||
Sys_user user = sysUserService.fetch(Cnd.where("loginname", "=", loginname));
|
||||
session.setAttribute("user", user);
|
||||
session.setAttribute("userId", user.getId());
|
||||
return ">>:/mobile/doLogin?username=" + loginname + "&password=dd3s@#2022&platformCaptcha=";
|
||||
}
|
||||
|
||||
private String getAccessToken() {
|
||||
TaskToken taskToken = dao.fetch(TaskToken.class, Cnd.where("token_type", "=", taskType));
|
||||
if (Lang.isNotEmpty(taskToken) && System.currentTimeMillis() / 1000 < (taskToken.getGet_time() + taskToken.getExpires_in() - 200)) {
|
||||
return taskToken.getToken();
|
||||
}
|
||||
accessTokenUrl = accessTokenUrl.formatted("wxf2f6f120053cf5eb", "eTGvDbfP3CpNibTNfpOOgIyv4KgRmJL7c7IDNXPD-kM");
|
||||
String access_token = Json.fromJson(NutMap.class, Http.get(accessTokenUrl).getContent()).getString("access_token");
|
||||
TaskToken t = new TaskToken();
|
||||
t.setToken(access_token);
|
||||
t.setExpires_in(7200);
|
||||
t.setToken_type(taskType);
|
||||
t.setGet_time(System.currentTimeMillis() / 1000);
|
||||
dao.clear("task_token", Cnd.where("token_type", "=", taskType));
|
||||
dao.insert("task_token", Chain.from(t));
|
||||
return access_token;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user