|
@@ -3,12 +3,15 @@ package com.skyversation.xjcy.oauth;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.skyversation.xjcy.util.HttpUtil;
|
|
import com.skyversation.xjcy.util.HttpUtil;
|
|
|
|
|
+import com.skyversation.xjcy.util.MessageManage;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.util.LinkedMultiValueMap;
|
|
import org.springframework.util.LinkedMultiValueMap;
|
|
|
import org.springframework.util.MultiValueMap;
|
|
import org.springframework.util.MultiValueMap;
|
|
|
import org.springframework.util.StringUtils;
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
|
|
|
|
+import java.security.MessageDigest;
|
|
|
|
|
+import java.security.NoSuchAlgorithmException;
|
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
|
import java.util.Objects;
|
|
import java.util.Objects;
|
|
@@ -16,6 +19,7 @@ import java.util.Objects;
|
|
|
@Service
|
|
@Service
|
|
|
public class AuthService {
|
|
public class AuthService {
|
|
|
|
|
|
|
|
|
|
+ private final WxAuthService wxAuthService;
|
|
|
@Value("${app.oauth.login-name}")
|
|
@Value("${app.oauth.login-name}")
|
|
|
private String loginName;
|
|
private String loginName;
|
|
|
@Value("${app.oauth.password}")
|
|
@Value("${app.oauth.password}")
|
|
@@ -25,38 +29,148 @@ public class AuthService {
|
|
|
|
|
|
|
|
private String cacheToken;
|
|
private String cacheToken;
|
|
|
|
|
|
|
|
- private String loginForToken() throws RuntimeException {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ public AuthService(WxAuthService wxAuthService) {
|
|
|
|
|
+ this.wxAuthService = wxAuthService;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private String loginForToken(String loginName, String password) throws RuntimeException {
|
|
|
|
|
+ JSONObject jsonObject = login(loginName, password);
|
|
|
|
|
+ if ("密码错误".equals(jsonObject.getString("message"))) {
|
|
|
|
|
+ throw new RuntimeException("请检查使用的账户和密码是否正确");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!Objects.equals(jsonObject.getString("code"), "200")) {
|
|
|
|
|
+ throw new RuntimeException(jsonObject.getString("message"));
|
|
|
|
|
+ }
|
|
|
|
|
+ return jsonObject.getString("message");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private JSONObject login(String loginName, String password) {
|
|
|
if (!StringUtils.hasText(loginName) || !StringUtils.hasText(password)) {
|
|
if (!StringUtils.hasText(loginName) || !StringUtils.hasText(password)) {
|
|
|
throw new RuntimeException("请提供用于访问DMS的账号密码");
|
|
throw new RuntimeException("请提供用于访问DMS的账号密码");
|
|
|
}
|
|
}
|
|
|
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
|
|
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
|
|
|
|
|
+ params.add("clientId", "2");
|
|
|
params.add("userName", loginName);
|
|
params.add("userName", loginName);
|
|
|
params.add("password", password);
|
|
params.add("password", password);
|
|
|
- params.add("clientId", "2");
|
|
|
|
|
- String response = HttpUtil.requestPost(oauthPath+"/api/user/login", params, new HashMap<>());
|
|
|
|
|
- JSONObject jsonObject = JSON.parseObject(response);
|
|
|
|
|
- if ("密码错误".equals(jsonObject.getString("message"))) {
|
|
|
|
|
- loginName = null;
|
|
|
|
|
- password = null;
|
|
|
|
|
- throw new RuntimeException("请检查使用的账户和密码是否正确,已停止使用该账号密码以避免锁定账号");
|
|
|
|
|
- }
|
|
|
|
|
- if (!Objects.equals(jsonObject.getString("code"), "200")) {
|
|
|
|
|
- throw new RuntimeException(jsonObject.getString("message"));
|
|
|
|
|
|
|
+ String response = HttpUtil.requestPost(oauthPath + "/api/user/login", params, new HashMap<>());
|
|
|
|
|
+ return JSON.parseObject(response);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private JSONObject register(String loginName, String password) {
|
|
|
|
|
+ if (!StringUtils.hasText(loginName) || !StringUtils.hasText(password)) {
|
|
|
|
|
+ throw new RuntimeException("请提供用于访问DMS的账号密码");
|
|
|
}
|
|
}
|
|
|
- return jsonObject.getString("message");
|
|
|
|
|
|
|
+ MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
|
|
|
|
|
+ params.add("userName", loginName);
|
|
|
|
|
+ params.add("password", password);
|
|
|
|
|
+ String response = HttpUtil.requestPost(oauthPath + "/user/register", params, new HashMap<>());
|
|
|
|
|
+ return JSON.parseObject(response);
|
|
|
}
|
|
}
|
|
|
- public boolean checkToken(String token){
|
|
|
|
|
|
|
+
|
|
|
|
|
+ private void initUser(int userId) {
|
|
|
|
|
+ //TODO 初始化用户
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 检查token有效性
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param token oauth系统的token
|
|
|
|
|
+ * @return 是否有效
|
|
|
|
|
+ */
|
|
|
|
|
+ @SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
|
|
|
+ public boolean checkToken(String token) {
|
|
|
Map<String, String> header = new HashMap<>();
|
|
Map<String, String> header = new HashMap<>();
|
|
|
header.put("token", token);
|
|
header.put("token", token);
|
|
|
- String response = HttpUtil.requestGet(oauthPath+"/user/validateToken",null,header);
|
|
|
|
|
|
|
+ String response = HttpUtil.requestGet(oauthPath + "/user/validateToken", null, header);
|
|
|
JSONObject jsonObject = JSON.parseObject(response);
|
|
JSONObject jsonObject = JSON.parseObject(response);
|
|
|
Integer code = jsonObject.getInteger("code");
|
|
Integer code = jsonObject.getInteger("code");
|
|
|
return Integer.valueOf(200).equals(code);
|
|
return Integer.valueOf(200).equals(code);
|
|
|
}
|
|
}
|
|
|
- public String getToken() throws RuntimeException {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取服务器内置的账户token
|
|
|
|
|
+ *
|
|
|
|
|
+ * @return 服务器内置账户的token
|
|
|
|
|
+ * @throws RuntimeException 内置账户信息异常
|
|
|
|
|
+ */
|
|
|
|
|
+ public String getTokenOfServiceAccount() throws RuntimeException {
|
|
|
if (!StringUtils.hasText(cacheToken) || !checkToken(cacheToken)) {
|
|
if (!StringUtils.hasText(cacheToken) || !checkToken(cacheToken)) {
|
|
|
- cacheToken = loginForToken();
|
|
|
|
|
|
|
+ cacheToken = loginForToken(this.loginName, this.password);
|
|
|
}
|
|
}
|
|
|
return cacheToken;
|
|
return cacheToken;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 通过wx的一键登录登录到oauth。
|
|
|
|
|
+ * 实际上每个wx用户都会被分配一个oauth账户,此账户以用户名与wx的openid建立连接。
|
|
|
|
|
+ * 逻辑上这个方法会尝试登录,无法登录时尝试建立oauth账户
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param wxCode wx.login()方法提供的一键登录用code
|
|
|
|
|
+ * @return 完整的response.body
|
|
|
|
|
+ */
|
|
|
|
|
+ public String logOrRegWxAccount(String wxCode) {
|
|
|
|
|
+ WxAuthService.Result wxResult = wxAuthService.wxLogin(wxCode);
|
|
|
|
|
+ if (wxResult.isSuccess()) {
|
|
|
|
|
+ //生成期望的绑定账户和密码
|
|
|
|
|
+ String oauthAccount = "#wx" + wxResult.getWxOpenId();
|
|
|
|
|
+ String oauthPassword = "Wx@" + encrypt(wxResult.getWxOpenId() + "chatWe");
|
|
|
|
|
+
|
|
|
|
|
+ //尝试登录
|
|
|
|
|
+ JSONObject result = login(oauthAccount, oauthPassword);
|
|
|
|
|
+ String message = result.getString("message");
|
|
|
|
|
+ Integer code = result.getInteger("code");
|
|
|
|
|
+ if (Integer.valueOf(200).equals(code)) {
|
|
|
|
|
+ return message;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //登录失败
|
|
|
|
|
+ if ("用户不存在".equals(message)) {
|
|
|
|
|
+ //尝试注册
|
|
|
|
|
+ JSONObject regResult = register(oauthAccount, oauthPassword);
|
|
|
|
|
+ if (!Integer.valueOf(200).equals(regResult.getInteger("code"))) {
|
|
|
|
|
+ return MessageManage.getInstance().getResultContent(-1, "注册失败,未知异常", "注册失败,未知异常");
|
|
|
|
|
+ }
|
|
|
|
|
+ JSONObject userUnInitResult = login(oauthAccount, oauthPassword);
|
|
|
|
|
+ if (!Integer.valueOf(200).equals(userUnInitResult.getInteger("code"))) {
|
|
|
|
|
+ return MessageManage.getInstance().getResultContent(-1, "注册失败,未知异常", "注册失败,未知异常");
|
|
|
|
|
+ }
|
|
|
|
|
+ Integer userId = userUnInitResult.getJSONObject("content").getInteger("id");
|
|
|
|
|
+ if (userId != null) {
|
|
|
|
|
+ initUser(userId);
|
|
|
|
|
+ }
|
|
|
|
|
+ return login(oauthAccount, oauthPassword).toJSONString();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return MessageManage.getInstance().getResultContent(-1, "未知异常", "未知异常");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return MessageManage.getInstance().getResultContent(-1, wxResult.getError(), wxResult.getError());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 简单sha-256加密,不加盐
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String encrypt(String input) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
|
|
|
|
+ byte[] hash = digest.digest(input.getBytes());
|
|
|
|
|
+
|
|
|
|
|
+ // 将字节数组转换为十六进制字符串
|
|
|
|
|
+ StringBuilder hexString = new StringBuilder();
|
|
|
|
|
+ for (byte b : hash) {
|
|
|
|
|
+ String hex = Integer.toHexString(0xff & b);
|
|
|
|
|
+ if (hex.length() == 1) {
|
|
|
|
|
+ hexString.append('0');
|
|
|
|
|
+ }
|
|
|
|
|
+ hexString.append(hex);
|
|
|
|
|
+ }
|
|
|
|
|
+ return hexString.toString();
|
|
|
|
|
+
|
|
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
|
|
+ throw new RuntimeException(e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|