|
|
@@ -0,0 +1,120 @@
|
|
|
+package com.uas.sso.util;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.uas.sso.common.encrypt.MD5;
|
|
|
+import com.uas.sso.common.util.HttpUtil;
|
|
|
+import com.uas.sso.core.Const;
|
|
|
+import com.uas.sso.core.ICallable;
|
|
|
+import com.uas.sso.entity.App;
|
|
|
+import com.uas.sso.entity.UserView;
|
|
|
+import com.uas.sso.exception.AccountException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
+import org.apache.log4j.Logger;
|
|
|
+import org.springframework.util.Assert;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Utils class is designed to sync user information with other apps
|
|
|
+ * and handle user information.
|
|
|
+ *
|
|
|
+ * @author huxz
|
|
|
+ */
|
|
|
+public class InfoAsyncUtils {
|
|
|
+
|
|
|
+ public static final Logger logger = Logger.getLogger(InfoAsyncUtils.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成加密密码
|
|
|
+ *
|
|
|
+ * @param format 密码加密格式
|
|
|
+ * @param password 明文密码
|
|
|
+ * @param salt 盐值
|
|
|
+ * @return 密文密码
|
|
|
+ */
|
|
|
+ public static String encryptePassword(String format, String password, String salt) {
|
|
|
+ // 验证加密格式
|
|
|
+ if (StringUtils.isEmpty(format)) {
|
|
|
+ return password;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证密码信息,长度超过32认为是已加密过的密文
|
|
|
+ int minPwdLen = 4;
|
|
|
+ int maxPwdLen = 32;
|
|
|
+ if (StringUtils.isEmpty(password) || password.length() < minPwdLen
|
|
|
+ || password.length() >= maxPwdLen) {
|
|
|
+ throw new AccountException("invalid password");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加密格式: "$password{$salt}"
|
|
|
+ String cipher = format.replace(Const.ENCRY_PARAM_PASSWORD, password);
|
|
|
+ cipher = cipher.replace(Const.ENCRY_PARAM_SALT, salt == null ? "" : salt);
|
|
|
+ return MD5.toMD5(cipher);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取所有应用的有效用户信息更新接口.
|
|
|
+ *
|
|
|
+ * @param appList 应用列表
|
|
|
+ * @return 用户更新接口链接列表
|
|
|
+ */
|
|
|
+ public static List<String> getUserBackUrlsFromApps(List<App> appList) {
|
|
|
+ if (CollectionUtils.isEmpty(appList)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> backUserUrls = new ArrayList<>();
|
|
|
+ for (App app : appList) {
|
|
|
+ if (app != null && StringUtils.isEmpty(app.getUserControl())
|
|
|
+ && !StringUtils.isEmpty(app.getBackUserUrl())) {
|
|
|
+ backUserUrls.add(app.getUid() + ":" + app.getBackUserUrl());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return backUserUrls;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 同步用户信息到各个应用
|
|
|
+ *
|
|
|
+ * @param backUserUrls 同步接口URL
|
|
|
+ * @param userView 用户信息视图
|
|
|
+ * @param msg 同步信息描述,用户区分同步类型
|
|
|
+ */
|
|
|
+ public static void syncUserInfo(final List<String> backUserUrls, final UserView userView,
|
|
|
+ final String msg) {
|
|
|
+ if (CollectionUtils.isEmpty(backUserUrls)) {
|
|
|
+ logger.warn("用户更新接口URL列表为空列表");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Assert.notNull(userView, "用户信息不能为空");
|
|
|
+ Assert.isTrue(!org.springframework.util.StringUtils.isEmpty(msg), "同步信息描述不能为空");
|
|
|
+
|
|
|
+ ExecuteUtils.execute(new ICallable<Void, String>() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Void call(String url) {
|
|
|
+ String[] split = url.split(":");
|
|
|
+ String appId = split[0];
|
|
|
+ try {
|
|
|
+ url = split[1];
|
|
|
+ JSONObject formData = JSON.parseObject(JSON.toJSONString(userView));
|
|
|
+
|
|
|
+ HttpUtil.ResponseWrap res = HttpUtil.doPost(url, formData, 30000);
|
|
|
+ if (!res.isSuccess()) {
|
|
|
+ logger.error(String.format("%s:同步用户信息失败, %s, %s, %s", msg, appId,
|
|
|
+ JSON.toJSONString(userView), res.getContent()));
|
|
|
+ } else {
|
|
|
+ logger.info(String.format("%s:同步用户信息成功, %s, %s", msg, appId,
|
|
|
+ JSON.toJSONString(userView)));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error(String.format("%s:同步用户信息失败, %s, %s, %s", msg, appId,
|
|
|
+ JSON.toJSONString(userView), e.getMessage()));
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }, backUserUrls);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|