xiatian 2 år sedan
förälder
incheckning
ed140b4f3b
1 ändrade filer med 82 tillägg och 3 borttagningar
  1. 82 3
      src/main/java/cn/com/qmth/mps/service/impl/AuthServiceImpl.java

+ 82 - 3
src/main/java/cn/com/qmth/mps/service/impl/AuthServiceImpl.java

@@ -3,6 +3,10 @@ package cn.com.qmth.mps.service.impl;
 import java.util.HashMap;
 import java.util.Map;
 
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -26,6 +30,7 @@ import cn.com.qmth.mps.util.HttpUtil;
 import cn.com.qmth.mps.util.SHA256;
 import cn.com.qmth.mps.vo.AdminLoginVo;
 import net.sf.json.JSONObject;
+import sun.misc.BASE64Decoder;
 
 @Service
 public class AuthServiceImpl implements AuthorizationService<User>, AuthService {
@@ -136,7 +141,7 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 	public void modifyWxappAccessToken() {
 		WxappAccessTokenEntity token = wxappAccessTokenService.getWxappAccessToken();
 		long now = System.currentTimeMillis();
-		if (StringUtils.isEmpty(token.getAccessToken()) || token.getExpiresTime()-now <= 15 * 60 * 1000) {
+		if (StringUtils.isEmpty(token.getAccessToken()) || token.getExpiresTime() - now <= 15 * 60 * 1000) {
 			Map<String, String> params = new HashMap<>();
 			params.put("appid", sysProperty.getWxappAppid());
 			params.put("secret", sysProperty.getWxappSecret());
@@ -161,8 +166,82 @@ public class AuthServiceImpl implements AuthorizationService<User>, AuthService
 
 	@Override
 	public AdminLoginVo loginWxAppEncryptedData(String wxappCode, String encryptedData, String iv) {
-		// TODO Auto-generated method stub
-		return null;
+		JSONObject jo=decrypt(encryptedData, iv, getSessionKey(wxappCode));
+		String phone=jo.getString("purePhoneNumber");
+		UserEntity userEntity = userService.getByLoginName(phone);
+		if (userEntity == null) {
+			throw new StatusException("微信所绑定手机号系统中不存在");
+		}
+		if (!userEntity.getEnable()) {
+			throw new StatusException("该用户已禁用");
+		}
+		if (!userEntity.getRoleId().equals(Role.SECTION_LEADER.getId())) {
+			throw new StatusException("该用户不是科组长");
+		}
+		User user = new User();
+		user.setName(userEntity.getName());
+		user.setSchoolId(userEntity.getSchoolId());
+		user.setId(userEntity.getId());
+		user.setRole(Role.getById(userEntity.getRoleId()));
+		user.setAccessToken(FastUUID.get());
+		user.buildKey();
+		sessionService.userLogin(user);
+		AdminLoginVo vo = new AdminLoginVo();
+		vo.setAccessToken(user.getAccessToken());
+		vo.setName(user.getName());
+		vo.setSessionId(user.getSessionId());
+		vo.setSchoolId(user.getSchoolId());
+		vo.setRole(user.getRole());
+		return vo;
+	}
+
+	private String getSessionKey(String wxappCode) {
+		Map<String, String> params = new HashMap<>();
+		params.put("appid", sysProperty.getWxappAppid());
+		params.put("secret", sysProperty.getWxappSecret());
+		params.put("js_code", wxappCode);
+		params.put("grant_type", "authorization_code");
+		String ret;
+		try {
+			ret = HttpUtil.httpActionGet("https://api.weixin.qq.com/sns/jscode2session", null, params);
+		} catch (Exception e) {
+			throw new StatusException("登录失败", e);
+		}
+		JSONObject jo = JSONObject.fromObject(ret);
+		if (jo.containsKey("errcode")) {
+			throw new StatusException("登录失败," + jo.getString("errmsg"));
+		}
+		return jo.getString("session_key");
 	}
 
+	private JSONObject decrypt(String encryptedData, String iv, String sessionKey){
+		String cipherString = "AES/CBC/PKCS5Padding";
+		String jsonStr;
+		try {
+			BASE64Decoder base64Decoder = new BASE64Decoder();
+			/**
+			 * 小程序加密数据解密算法
+			 * https://developers.weixin.qq.com/miniprogram/dev/api/signature.html#wxchecksessionobject
+			 * 1.对称解密的目标密文为 Base64_Decode(encryptedData)。 2.对称解密秘钥 aeskey =
+			 * Base64_Decode(session_key), aeskey 是16字节。 3.对称解密算法初始向量
+			 * 为Base64_Decode(iv),其中iv由数据接口返回。
+			 */
+			byte[] encryptedByte = base64Decoder.decodeBuffer(encryptedData);
+			byte[] sessionKeyByte = base64Decoder.decodeBuffer(sessionKey);
+			byte[] ivByte = base64Decoder.decodeBuffer(iv);
+			/**
+			 * 以下为AES-128-CBC解密算法
+			 */
+			SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyByte, "AES");
+			Cipher cipher = Cipher.getInstance(cipherString);
+			IvParameterSpec ivParameterSpec = new IvParameterSpec(ivByte);
+			cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);
+			byte[] original = cipher.doFinal(encryptedByte);
+			jsonStr = new String(original);
+		} catch (Exception e) {
+			throw new StatusException("登录失败,信息有误 ",e);
+		}
+		JSONObject jsonObject = JSONObject.fromObject(jsonStr);
+		return jsonObject;
+	}
 }