diff --git a/JSD-8431-需求确认书V1.docx b/JSD-8431-需求确认书V1.docx
new file mode 100644
index 0000000..31d75af
Binary files /dev/null and b/JSD-8431-需求确认书V1.docx differ
diff --git a/JSD-8431配置使用文档.docx b/JSD-8431配置使用文档.docx
new file mode 100644
index 0000000..a737307
Binary files /dev/null and b/JSD-8431配置使用文档.docx differ
diff --git a/README.md b/README.md
index a4139ea..1f967f3 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,3 @@
-# open-JSD-8431
+# open-JSD-8431 OAuth2单点+用户同步
JSD-8431开源任务材料
\ No newline at end of file
diff --git a/lib/commons-beanutils-1.8.0.jar b/lib/commons-beanutils-1.8.0.jar
new file mode 100644
index 0000000..caf7ae3
Binary files /dev/null and b/lib/commons-beanutils-1.8.0.jar differ
diff --git a/lib/commons-collections-3.2.1.jar b/lib/commons-collections-3.2.1.jar
new file mode 100644
index 0000000..c35fa1f
Binary files /dev/null and b/lib/commons-collections-3.2.1.jar differ
diff --git a/lib/commons-lang-2.5.jar b/lib/commons-lang-2.5.jar
new file mode 100644
index 0000000..ae491da
Binary files /dev/null and b/lib/commons-lang-2.5.jar differ
diff --git a/lib/commons-logging-1.1.1.jar b/lib/commons-logging-1.1.1.jar
new file mode 100644
index 0000000..1deef14
Binary files /dev/null and b/lib/commons-logging-1.1.1.jar differ
diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar
new file mode 100644
index 0000000..f4482fc
Binary files /dev/null and b/lib/finekit-10.0.jar differ
diff --git a/lib/json-lib-2.4-jdk15.jar b/lib/json-lib-2.4-jdk15.jar
new file mode 100644
index 0000000..68d4f3b
Binary files /dev/null and b/lib/json-lib-2.4-jdk15.jar differ
diff --git a/plugin.xml b/plugin.xml
new file mode 100644
index 0000000..5df3480
--- /dev/null
+++ b/plugin.xml
@@ -0,0 +1,25 @@
+
+
+ com.fr.plugin.hdmu.sso
+
+ yes
+ 1.2.4
+ 10.0
+ 2018-07-31
+ mqh
+
+
+ com.fr.plugin.hdmu
+
+ com.fanruan.api
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/LocaleFinder.java b/src/main/java/com/fr/plugin/hdmu/LocaleFinder.java
new file mode 100644
index 0000000..fafbddc
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/LocaleFinder.java
@@ -0,0 +1,37 @@
+ /*
+ * Copyright (C), 2018-2020
+ * Project: starter
+ * FileName: LocaleFinder
+ * Author: Louis
+ * Date: 2020/8/31 22:19
+ */
+ package com.fr.plugin.hdmu;
+
+ import com.fr.intelli.record.Focus;
+import com.fr.intelli.record.Original;
+import com.fr.record.analyzer.EnableMetrics;
+import com.fr.stable.fun.impl.AbstractLocaleFinder;
+
+import static com.fr.plugin.hdmu.config.SsoConfig.PLUGIN_ID;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ @EnableMetrics
+ public class LocaleFinder extends AbstractLocaleFinder {
+
+ @Override
+ @Focus(id = PLUGIN_ID, text = "Plugin-hdmu", source = Original.PLUGIN)
+ public String find() {
+ return "com/fr/plugin/hdmu/locale/lang";
+ }
+
+ @Override
+ public int currentAPILevel() {
+ return CURRENT_LEVEL;
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/PluginMonitor.java b/src/main/java/com/fr/plugin/hdmu/PluginMonitor.java
new file mode 100644
index 0000000..617b212
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/PluginMonitor.java
@@ -0,0 +1,50 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: PluginMonitor
+ * Author: Louis
+ * Date: 2021/3/30 15:10
+ */
+ package com.fr.plugin.hdmu;
+
+ import com.fanruan.api.log.LogKit;
+ import com.fr.plugin.context.PluginContext;
+ import com.fr.plugin.hdmu.config.SsoConfig;
+ import com.fr.plugin.hdmu.helper.SsoUserScheduleHelper;
+ import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor;
+
+ import static com.fr.plugin.hdmu.helper.SsoUserScheduleHelper.SSO_USER_SCHEDULE_SYN_MEMBER_GROUP;
+ import static com.fr.plugin.hdmu.helper.SsoUserScheduleHelper.SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME;
+
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class PluginMonitor extends AbstractPluginLifecycleMonitor {
+ public PluginMonitor() {
+ }
+
+ @Override
+ public void afterRun(PluginContext pluginContext) {
+ SsoConfig.getInstance();
+ this.reStartSchedule();
+ }
+
+ @Override
+ public void beforeStop(PluginContext pluginContext) {
+ SsoUserScheduleHelper.getInstance().stopSchedule(SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME, SSO_USER_SCHEDULE_SYN_MEMBER_GROUP);
+ }
+
+ private void reStartSchedule() {
+ try {
+ String cronCondition = SsoConfig.getInstance().getCronCondition();
+ SsoUserScheduleHelper.getInstance().startSynMemberSchedule(cronCondition);
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/bean/SsoUserJobConstructor.java b/src/main/java/com/fr/plugin/hdmu/bean/SsoUserJobConstructor.java
new file mode 100644
index 0000000..1f1ebb9
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/bean/SsoUserJobConstructor.java
@@ -0,0 +1,107 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: SsoUserJobConstructor
+ * Author: Louis
+ * Date: 2021/4/21 15:58
+ */
+ package com.fr.plugin.hdmu.bean;
+
+ import com.fr.scheduler.job.FineScheduleJob;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class SsoUserJobConstructor {
+ private String cron;
+ private String jobName;
+ private String jobGroup;
+ private String triggerName;
+ private String triggerGroup;
+ private Class extends FineScheduleJob> jobClazz;
+
+ public SsoUserJobConstructor() {
+ }
+
+ public SsoUserJobConstructor cron(String var1) {
+ this.setCron(var1);
+ return this;
+ }
+
+ public String getCron() {
+ return this.cron;
+ }
+
+ public void setCron(String var1) {
+ this.cron = var1;
+ }
+
+ public SsoUserJobConstructor jobName(String var1) {
+ this.setJobName(var1);
+ return this;
+ }
+
+ public String getJobName() {
+ return this.jobName;
+ }
+
+ public void setJobName(String var1) {
+ this.jobName = var1;
+ }
+
+ public SsoUserJobConstructor jobGroup(String var1) {
+ this.setJobGroup(var1);
+ return this;
+ }
+
+ public String getJobGroup() {
+ return this.jobGroup;
+ }
+
+ public void setJobGroup(String var1) {
+ this.jobGroup = var1;
+ }
+
+ public SsoUserJobConstructor triggerName(String var1) {
+ this.setTriggerName(var1);
+ return this;
+ }
+
+ public String getTriggerName() {
+ return this.triggerName;
+ }
+
+ public void setTriggerName(String var1) {
+ this.triggerName = var1;
+ }
+
+ public SsoUserJobConstructor triggerGroup(String var1) {
+ this.setTriggerGroup(var1);
+ return this;
+ }
+
+ public String getTriggerGroup() {
+ return this.triggerGroup;
+ }
+
+ public void setTriggerGroup(String var1) {
+ this.triggerGroup = var1;
+ }
+
+ public SsoUserJobConstructor jobClazz(Class extends FineScheduleJob> var1) {
+ this.setJobClazz(var1);
+ return this;
+ }
+
+ public Class extends FineScheduleJob> getJobClazz() {
+ return this.jobClazz;
+ }
+
+ public void setJobClazz(Class extends FineScheduleJob> var1) {
+ this.jobClazz = var1;
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/config/SsoConfig.java b/src/main/java/com/fr/plugin/hdmu/config/SsoConfig.java
new file mode 100644
index 0000000..5d3fae5
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/config/SsoConfig.java
@@ -0,0 +1,123 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: SsoConfig
+ * Author: Louis
+ * Date: 2021/3/30 9:38
+ */
+ package com.fr.plugin.hdmu.config;
+
+ import com.fanruan.api.util.StringKit;
+ import com.fr.config.*;
+ import com.fr.config.holder.Conf;
+ import com.fr.config.holder.factory.Holders;
+ import com.fr.intelli.record.Focus;
+ import com.fr.intelli.record.Original;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ @Visualization(category = "Plugin-hdmu_Group")
+ public class SsoConfig extends DefaultConfiguration {
+ public static final String PLUGIN_ID = "com.fr.plugin.hdmu.sso";
+ public static final String BASE_URI = "https://127.0.0";
+ public static final String URI_IAM = "https://xxx";
+ // 每天中午十二点触发
+ public static final String CRON_CONDITION = "0 0 12 * * ?";
+ public static final String ROOT_DEP_ID = "ROOT";
+
+ private static volatile SsoConfig config = null;
+
+ @Focus(id = PLUGIN_ID, text = "Plugin-hdmu", source = Original.PLUGIN)
+ public static SsoConfig getInstance() {
+ if (config == null) {
+ config = ConfigContext.getConfigInstance(SsoConfig.class);
+ }
+ return config;
+ }
+
+ @Identifier(value = "clientId", name = "Plugin-hdmu_Config_ClientId", description = "Plugin-hdmu_Config_ClientId_Description", status = Status.SHOW)
+ private Conf clientId = Holders.simple(StringKit.EMPTY);
+ @Identifier(value = "clientSecret", name = "Plugin-hdmu_Config_ClientSecret", description = "Plugin-hdmu_Config_ClientSecret_Description", status = Status.SHOW)
+ private Conf clientSecret = Holders.simple(StringKit.EMPTY);
+ @Identifier(value = "uriBase", name = "Plugin-hdmu_Config_UriBase", description = "Plugin-hdmu_Config_UriBase_Description", status = Status.SHOW)
+ private Conf uriBase = Holders.simple(BASE_URI);
+ @Identifier(value = "frUri", name = "Plugin-hdmu_Config_FrUri", description = "Plugin-hdmu_Config_FrUri_Description", status = Status.SHOW)
+ private Conf frUri = Holders.simple(StringKit.EMPTY);
+ @Identifier(value = "appID", name = "Plugin-hdmu_Config_AppID", description = "Plugin-hdmu_Config_AppID_Description", status = Status.SHOW)
+ private Conf appID = Holders.simple(StringKit.EMPTY);
+ @Identifier(value = "cronCondition", name = "Plugin-hdmu_Config_CronCondition", description = "Plugin-hdmu_Config_CronCondition_Description", status = Status.SHOW)
+ private Conf cronCondition = Holders.simple(CRON_CONDITION);
+ @Identifier(value = "uriIam", name = "Plugin-hdmu_Config_UriIam", description = "Plugin-hdmu_Config_UriIam_Description", status = Status.SHOW)
+ private Conf uriIam = Holders.simple(URI_IAM);
+ @Identifier(value = "appIamKey", name = "Plugin-hdmu_Config_AppIamKey", description = "Plugin-hdmu_Config_AppIamKey_Description", status = Status.SHOW)
+ private Conf appIamKey = Holders.simple(StringKit.EMPTY);
+
+ public String getClientId() {
+ return clientId.get();
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId.set(clientId);
+ }
+
+ public String getClientSecret() {
+ return clientSecret.get();
+ }
+
+ public void setClientSecret(String clientSecret) {
+ this.clientSecret.set(clientSecret);
+ }
+
+ public String getUriBase() {
+ return uriBase.get();
+ }
+
+ public void setUriBase(String uriBase) {
+ this.uriBase.set(uriBase);
+ }
+
+ public String getFrUri() {
+ return frUri.get();
+ }
+
+ public void setFrUri(String frUri) {
+ this.frUri.set(frUri);
+ }
+
+ public String getCronCondition() {
+ return cronCondition.get();
+ }
+
+ public void setCronCondition(String cronCondition) {
+ this.cronCondition.set(cronCondition);
+ }
+
+ public String getAppID() {
+ return appID.get();
+ }
+
+ public void setAppID(String appID) {
+ this.appID.set(appID);
+ }
+
+ public String getUriIam() {
+ return uriIam.get();
+ }
+
+ public void setUriIam(String uriIam) {
+ this.uriIam.set(uriIam);
+ }
+
+ public String getAppIamKey() {
+ return appIamKey.get();
+ }
+
+ public void setAppIamKey(String appIamKey) {
+ this.appIamKey.set(appIamKey);
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/helper/SsoUserScheduleHelper.java b/src/main/java/com/fr/plugin/hdmu/helper/SsoUserScheduleHelper.java
new file mode 100644
index 0000000..89ac3b9
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/helper/SsoUserScheduleHelper.java
@@ -0,0 +1,77 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: SsoUserScheduleHelper
+ * Author: Louis
+ * Date: 2021/4/21 15:52
+ */
+ package com.fr.plugin.hdmu.helper;
+
+ import com.fr.plugin.hdmu.bean.SsoUserJobConstructor;
+ import com.fr.plugin.hdmu.job.SsoUserSyncMemberJob;
+ import com.fr.scheduler.ScheduleJobManager;
+ import com.fr.third.v2.org.quartz.CronScheduleBuilder;
+ import com.fr.third.v2.org.quartz.TriggerBuilder;
+
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.TimeZone;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class SsoUserScheduleHelper {
+ public static final String SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME = "MqhSsoUserSynDepMemberJob";
+ public static final String SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_NAME = "MqhSsoUserSynDepMemberTrigger";
+ public static final String SSO_USER_SCHEDULE_SYN_MEMBER_GROUP = "MqhSsoUserSynDepMemberGroup";
+ public static final String SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_GROUP = "MqhSsoUserSynDepMemberTriggerGroup";
+
+ private SsoUserScheduleHelper() {
+ }
+
+ public static SsoUserScheduleHelper getInstance() {
+ return HOLDER.INSTANCE;
+ }
+
+ public void startSynMemberSchedule(String cronCondition) throws Exception {
+ SsoUserJobConstructor jobConstructor = (new SsoUserJobConstructor())
+ .cron(cronCondition).jobName(SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME)
+ .jobGroup(SSO_USER_SCHEDULE_SYN_MEMBER_GROUP).triggerName(SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_NAME)
+ .triggerGroup(SSO_USER_SCHEDULE_SYN_MEMBER_TRIGGER_GROUP).jobClazz(SsoUserSyncMemberJob.class);
+ this.startSchedule(jobConstructor);
+ }
+
+ public void startSchedule(SsoUserJobConstructor var1) throws Exception {
+ if (var1 != null) {
+ String var2 = var1.getCron();
+ String var3 = var1.getTriggerName();
+ String var4 = var1.getTriggerGroup();
+ String var5 = var1.getJobName();
+ String var6 = var1.getJobGroup();
+ Class var7 = var1.getJobClazz();
+ TriggerBuilder var8 = TriggerBuilder.newTrigger();
+ var8.withIdentity(var3, var4);
+ var8.withSchedule(CronScheduleBuilder.cronSchedule(var2).withMisfireHandlingInstructionFireAndProceed().inTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID()))).startNow();
+ var8.forJob(var5, var6);
+ ArrayList var9 = new ArrayList();
+ var9.add(var8.build());
+ ScheduleJobManager.getInstance().removeJob(var5, var6);
+ ScheduleJobManager.getInstance().addJob(var5, var6, "jobDescription", var7, var9, new HashMap());
+ }
+ }
+
+ public void stopSchedule(String var1, String var2) {
+ ScheduleJobManager.getInstance().removeJob(var1, var2);
+ }
+
+ public static class HOLDER {
+ private static final SsoUserScheduleHelper INSTANCE = new SsoUserScheduleHelper();
+
+ public HOLDER() {
+ }
+ }
+ }
diff --git a/src/main/java/com/fr/plugin/hdmu/job/SsoUserSyncMemberJob.java b/src/main/java/com/fr/plugin/hdmu/job/SsoUserSyncMemberJob.java
new file mode 100644
index 0000000..9fb3ea5
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/job/SsoUserSyncMemberJob.java
@@ -0,0 +1,34 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: SsoUserSyncMemberJob
+ * Author: Louis
+ * Date: 2021/4/21 16:02
+ */
+ package com.fr.plugin.hdmu.job;
+
+ import com.fanruan.api.log.LogKit;
+ import com.fr.cluster.core.ClusterNode;
+ import com.fr.plugin.hdmu.user.SsoUserManager;
+ import com.fr.scheduler.job.FineScheduleJob;
+ import com.fr.third.v2.org.quartz.JobExecutionContext;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class SsoUserSyncMemberJob extends FineScheduleJob {
+ public SsoUserSyncMemberJob() {
+ }
+
+ public void run(JobExecutionContext jobExecutionContext, ClusterNode clusterNode) {
+ try {
+ SsoUserManager.getInstance().synSSODepartments();
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/kit/DepartmentServiceKit.java b/src/main/java/com/fr/plugin/hdmu/kit/DepartmentServiceKit.java
new file mode 100644
index 0000000..60b3a37
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/kit/DepartmentServiceKit.java
@@ -0,0 +1,87 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: DepartmentServiceKit
+ * Author: Louis
+ * Date: 2021/5/14 9:38
+ */
+ package com.fr.plugin.hdmu.kit;
+
+ import com.fanruan.api.util.StringKit;
+ import com.fr.decision.authority.AuthorityContext;
+ import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
+ import com.fr.decision.authority.data.Department;
+ import com.fr.decision.webservice.exception.general.DuplicatedNameException;
+ import com.fr.decision.webservice.v10.user.DepartmentService;
+ import com.fr.general.ComparatorUtils;
+ import com.fr.plugin.hdmu.config.SsoConfig;
+ import com.fr.stable.query.QueryFactory;
+ import com.fr.stable.query.condition.QueryCondition;
+ import com.fr.stable.query.restriction.Restriction;
+ import com.fr.stable.query.restriction.RestrictionFactory;
+
+ import static com.fr.decision.authority.base.AuthorityConstants.DECISION_DEP_ROOT;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class DepartmentServiceKit extends DepartmentService {
+ private static volatile DepartmentServiceKit departmentServiceKit = null;
+
+ public DepartmentServiceKit() {
+ }
+
+ public static DepartmentServiceKit getInstance() {
+ if (departmentServiceKit == null) {
+ departmentServiceKit = new DepartmentServiceKit();
+ }
+ return departmentServiceKit;
+ }
+
+ /**
+ * 根部门与FR根部门转换
+ *
+ * @param parentId
+ * @return
+ */
+ public String changeRootId(String parentId) {
+ if (StringKit.isBlank(parentId) || StringKit.equals(parentId, SsoConfig.ROOT_DEP_ID)) {
+ return DECISION_DEP_ROOT;
+ }
+ return parentId;
+ }
+
+ public void addDepartment(String id, String pId, String depName) throws Exception {
+ if (StringKit.equals(pId, DECISION_DEP_ROOT)) {
+ pId = null;
+ }
+ this.checkDuplicatedDepartmentName(pId, depName);
+ Department department = (new Department()).id(id).name(depName).parentId(pId).creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true);
+ AuthorityContext.getInstance().getDepartmentController().add(department);
+ }
+
+ private void checkDuplicatedDepartmentName(String parentId, String depName) throws Exception {
+ QueryCondition condition = QueryFactory.create().addRestriction(RestrictionFactory.and(new Restriction[]{RestrictionFactory.eq("name", depName), RestrictionFactory.eq("parentId", parentId)}));
+ Department sameNameDep = AuthorityContext.getInstance().getDepartmentController().findOne(condition);
+ if (sameNameDep != null) {
+ throw new DuplicatedNameException();
+ }
+ }
+
+ public void editDepartment(String departmentId, String depName, String pId) throws Exception {
+ if (StringKit.equals(pId, DECISION_DEP_ROOT)) {
+ pId = null;
+ }
+ Department department = AuthorityContext.getInstance().getDepartmentController().getById(departmentId);
+ if (!ComparatorUtils.equals(department.getName(), depName)) {
+ this.checkDuplicatedDepartmentName(department.getParentId(), depName);
+ department.setName(depName);
+ department.setParentId(pId);
+ AuthorityContext.getInstance().getDepartmentController().update(department);
+ }
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/kit/PositionServiceKit.java b/src/main/java/com/fr/plugin/hdmu/kit/PositionServiceKit.java
new file mode 100644
index 0000000..b874fe3
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/kit/PositionServiceKit.java
@@ -0,0 +1,54 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: PositionServiceKit
+ * Author: Louis
+ * Date: 2021/8/18 15:38
+ */
+ package com.fr.plugin.hdmu.kit;
+
+ import com.fr.decision.authority.AuthorityContext;
+ import com.fr.decision.authority.base.constant.SoftRoleType;
+ import com.fr.decision.authority.base.constant.type.operation.ManualOperationType;
+ import com.fr.decision.authority.data.Post;
+ import com.fr.decision.record.OperateMessage;
+ import com.fr.decision.webservice.v10.user.PositionService;
+ import com.fr.intelli.record.MetricRegistry;
+ import com.fr.stable.query.QueryFactory;
+ import com.fr.stable.query.condition.QueryCondition;
+ import com.fr.stable.query.restriction.Restriction;
+ import com.fr.stable.query.restriction.RestrictionFactory;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class PositionServiceKit extends PositionService {
+ private static volatile PositionServiceKit positionServiceKit = null;
+
+ public PositionServiceKit() {
+ }
+
+ public static PositionServiceKit getInstance() {
+ if (positionServiceKit == null) {
+ positionServiceKit = new PositionServiceKit();
+ }
+ return positionServiceKit;
+ }
+
+ public String addPosition(String id, String name, String desc) throws Exception {
+ Post post = (new Post()).id(id).name(name).creationType(ManualOperationType.KEY).lastOperationType(ManualOperationType.KEY).enable(true).description(desc);
+ AuthorityContext.getInstance().getPostController().add(post);
+ this.deleteSoftData(post.getName());
+ MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-Post", name, "Dec-Log_Add"));
+ return post.getId();
+ }
+
+ private void deleteSoftData(String var1) throws Exception {
+ QueryCondition var2 = QueryFactory.create().addRestriction(RestrictionFactory.and(new Restriction[]{RestrictionFactory.eq("deletedName", var1), RestrictionFactory.eq("type", SoftRoleType.POST)}));
+ AuthorityContext.getInstance().getSoftDataController().remove(var2);
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/kit/UserServiceKit.java b/src/main/java/com/fr/plugin/hdmu/kit/UserServiceKit.java
new file mode 100644
index 0000000..a0bcfba
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/kit/UserServiceKit.java
@@ -0,0 +1,156 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: UserServiceKit
+ * Author: Louis
+ * Date: 2021/5/14 8:28
+ */
+ package com.fr.plugin.hdmu.kit;
+
+ import com.fanruan.api.log.LogKit;
+ import com.fanruan.api.util.StringKit;
+ import com.fr.decision.authority.AuthorityContext;
+ import com.fr.decision.authority.data.User;
+ import com.fr.decision.privilege.TransmissionTool;
+ import com.fr.decision.webservice.bean.user.DepartmentPostBean;
+ import com.fr.decision.webservice.bean.user.UserBean;
+ import com.fr.decision.webservice.v10.user.PositionService;
+ import com.fr.decision.webservice.v10.user.UserService;
+ import com.fr.json.JSONObject;
+
+ import java.util.ArrayList;
+ import java.util.List;
+
+ import static com.fr.plugin.hdmu.user.SsoUserManager.JOB_CODE;
+ import static com.fr.plugin.hdmu.user.SsoUserManager.ORG_CODE;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class UserServiceKit extends UserService {
+ public static final String USER_NAME = "uid";
+ public static final String REAL_NAME = "userName";
+ public static final String ENABLE = "status";
+ public static final String EMAIL = "email";
+ public static final String MOBILE = "mobile";
+ public static final String PASSWORD = "appPwd";
+ private static volatile UserServiceKit userServiceKit = null;
+
+ public UserServiceKit() {
+ }
+
+ public static UserServiceKit getInstance() {
+ if (userServiceKit == null) {
+ userServiceKit = new UserServiceKit();
+ }
+ return userServiceKit;
+ }
+
+ public UserBean createUserBean(JSONObject account) throws Exception {
+ UserBean userBean = new UserBean();
+ userBean.setUsername(account.getString(USER_NAME));
+ userBean.setRealName(account.getString(REAL_NAME));
+ userBean.setEnable(StringKit.equals(account.getJSONArray("userJobAttr").getJSONObject(0).getString(ENABLE), "1"));
+ userBean.setEmail(account.getString(EMAIL));
+ userBean.setMobile(account.getString(MOBILE));
+ userBean.setPassword(TransmissionTool.defaultEncrypt(account.getString(PASSWORD)));
+ String departmentId;
+ String position;
+ try {
+ departmentId = account.getString(ORG_CODE);
+ position = account.getString(JOB_CODE);
+ } catch (Exception e) {
+ departmentId = StringKit.EMPTY;
+ position = StringKit.EMPTY;
+ }
+ if (StringKit.isNotBlank(departmentId)) {
+ List departmentPostIds = createDepartmentPostIds(departmentId, position);
+ userBean.setDepartmentPostIds(departmentPostIds);
+ }
+ return userBean;
+ }
+
+ /**
+ * 转为部门职务组合
+ *
+ * @param departmentPostId
+ * @param positionId
+ * @return
+ * @throws Exception
+ */
+ private List createDepartmentPostIds(String departmentPostId, String positionId) throws Exception {
+ List departmentPostIds = new ArrayList<>();
+ if (StringKit.isBlank(departmentPostId) || StringKit.equals(departmentPostId, "null")) {
+ return departmentPostIds;
+ }
+ if (StringKit.isNotBlank(positionId)) {
+ String positionName = PositionServiceKit.getInstance().getPostNameById(positionId);
+ List departmentPostBeanList = PositionService.getInstance().getPositionsUnderParentDepartment(getAdminUserId(), departmentPostId, positionName);
+ if (departmentPostBeanList == null || departmentPostBeanList.isEmpty()) {
+ try {
+ AuthorityContext.getInstance().getPostController().addPostToDepartment(positionId, departmentPostId);
+ } catch (Exception e) {
+ LogKit.info("sso-UserServiceKit-createDepartmentPostIds-addPostToDepartmentFailed-position:{}, departmentId:{}", positionId + positionName, departmentPostId);
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+ departmentPostId = departmentPostId + "@@@" + positionId;
+ }
+ departmentPostIds.add(departmentPostId);
+ return departmentPostIds;
+ }
+
+ /**
+ * 获取管理员id
+ *
+ * @return
+ * @throws Exception
+ */
+ public String getAdminUserId() throws Exception {
+ List adminUserIdList = UserService.getInstance().getAdminUserIdList();
+ if (adminUserIdList.isEmpty()) {
+ return "admin";
+ }
+ return StringKit.isNotBlank(adminUserIdList.get(0)) ? adminUserIdList.get(0) : "admin";
+ }
+
+ @Override
+ public void editUser(UserBean userBean) throws Exception {
+ super.editUser(userBean);
+ this.forbidUser(userBean.getId(), userBean.isEnable());
+ this.updateUserDepartmentPost(this.getAdminUserId(), userBean);
+ }
+
+ public UserBean updateUserBean(JSONObject account) throws Exception {
+ User user = UserService.getInstance().getUserByUserName(account.getString(USER_NAME));
+ if (user == null) {
+ return null;
+ }
+ UserBean userBean = new UserBean();
+ userBean.setId(user.getId());
+ userBean.setUsername(user.getUserName());
+ userBean.setRealName(account.getString(REAL_NAME));
+ userBean.setEnable(StringKit.equals(account.getJSONArray("userJobAttr").getJSONObject(0).getString(ENABLE), "1"));
+ userBean.setEmail(account.getString(EMAIL));
+ userBean.setMobile(account.getString(MOBILE));
+ userBean.setPassword(TransmissionTool.defaultEncrypt(account.getString(PASSWORD)));
+ String departmentId;
+ String position;
+ try {
+ departmentId = account.getString(ORG_CODE);
+ position = account.getString(JOB_CODE);
+ } catch (Exception e) {
+ departmentId = StringKit.EMPTY;
+ position = StringKit.EMPTY;
+ }
+ if (StringKit.isNotBlank(departmentId)) {
+ List departmentPostIds = createDepartmentPostIds(departmentId, position);
+ userBean.setDepartmentPostIds(departmentPostIds);
+ }
+ return userBean;
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/request/HttpAuthorizeBridge.java b/src/main/java/com/fr/plugin/hdmu/request/HttpAuthorizeBridge.java
new file mode 100644
index 0000000..123ed8b
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/request/HttpAuthorizeBridge.java
@@ -0,0 +1,32 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: HttpAuthorizeBridge
+ * Author: Louis
+ * Date: 2021/8/24 13:55
+ */
+ package com.fr.plugin.hdmu.request;
+
+ import com.fanruan.api.util.StringKit;
+ import com.fr.decision.fun.impl.AbstractHttpAuthorizeProvider;
+ import com.fr.security.SecurityToolbox;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class HttpAuthorizeBridge extends AbstractHttpAuthorizeProvider {
+ @Override
+ public Scope scope() {
+ return Scope.REPLACE;
+ }
+
+ @Override
+ public boolean authorize(String inputUsername, String inputPassword, String savedPassword, String hashPassword) {
+ String encryptPwd = SecurityToolbox.sha256(SecurityToolbox.sha256(inputPassword));
+ return StringKit.equalsIgnoreCase(encryptPwd, savedPassword);
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/request/OAuthLogin.java b/src/main/java/com/fr/plugin/hdmu/request/OAuthLogin.java
new file mode 100644
index 0000000..2bf50e3
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/request/OAuthLogin.java
@@ -0,0 +1,220 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: OAuthLogin
+ * Author: Louis
+ * Date: 2021/3/30 22:09
+ */
+ package com.fr.plugin.hdmu.request;
+
+ import com.fanruan.api.decision.login.LoginKit;
+ import com.fanruan.api.decision.user.UserKit;
+ import com.fanruan.api.log.LogKit;
+ import com.fanruan.api.net.NetworkKit;
+ import com.fanruan.api.util.StringKit;
+ import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider;
+ import com.fr.decision.webservice.utils.DecisionServiceConstants;
+ import com.fr.decision.webservice.v10.login.LoginService;
+ import com.fr.json.JSONObject;
+ import com.fr.plugin.hdmu.config.SsoConfig;
+ import com.fr.plugin.hdmu.utils.HttpRequestUtil;
+ import com.fr.third.org.apache.http.client.utils.URIBuilder;
+
+ import javax.servlet.FilterChain;
+ import javax.servlet.FilterConfig;
+ import javax.servlet.http.HttpServletRequest;
+ import javax.servlet.http.HttpServletResponse;
+ import java.net.URISyntaxException;
+ import java.util.HashMap;
+ import java.util.Map;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class OAuthLogin extends AbstractGlobalRequestFilterProvider {
+ public static final String REMOTE_DESIGN = "/remote/design";
+ public static final String RESOURCES_PATH = "/resources";
+ public static final String FILE_PATH = "/file";
+ public static final String SYSTEM_INFO = "/system/info";
+ public static final String MATERIALS_MIN_JS_MAP = "/materials.min.js.map";
+ public static final String LOGIN_PATH = "/login";
+ public static final String LOGIN_OTHER = "/login/";
+ public static final String LOGOUT_PATH = "/logout";
+ public static final String USER_LANGUAGE = "/v10/user/language";
+ public static final String SYSTEM_HEALTH = "/system/health";
+ public static final String USER_SYN = "/syn";
+
+ public static final String CODE_URL = "/profile/oauth2/authorize";
+ public static final String TOKEN_URL = "/profile/oauth2/accessToken";
+ public static final String USER_URL = "/profile/oauth2/profile";
+ public static final String CODE = "code";
+ public static final String STATE = "sso";
+
+ private SsoConfig config;
+
+ /**
+ * 过滤器名称
+ *
+ * @return
+ */
+ @Override
+ public String filterName() {
+ return "hdmuFilter";
+ }
+
+ /**
+ * 过滤规则
+ *
+ * @return
+ */
+ @Override
+ public String[] urlPatterns() {
+ return new String[]{"/*"};
+ }
+
+ /**
+ * 过滤器初始化
+ *
+ * @param filterConfig
+ */
+ @Override
+ public void init(FilterConfig filterConfig) {
+ this.config = SsoConfig.getInstance();
+ super.init(filterConfig);
+ }
+
+ /**
+ * 过滤器处理
+ *
+ * @param request
+ * @param response
+ * @param filterChain
+ */
+ @Override
+ public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
+ try {
+ if (operation(request, response)) {
+ filterChain.doFilter(request, response);
+ }
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * 用户验证登陆操作
+ *
+ * @param req
+ * @param res
+ * @throws Exception
+ */
+ private boolean operation(HttpServletRequest req, HttpServletResponse res) throws Exception {
+ String pathInfo = (req.getPathInfo() != null) ? req.getPathInfo() : StringKit.EMPTY;
+ if (pathInfo.startsWith(REMOTE_DESIGN) || pathInfo.startsWith(LOGIN_OTHER)
+ || StringKit.equals(LOGIN_PATH, pathInfo) || pathInfo.startsWith(USER_SYN)
+ || pathInfo.startsWith(RESOURCES_PATH) || pathInfo.startsWith(LOGOUT_PATH)
+ || pathInfo.startsWith(SYSTEM_INFO) || pathInfo.startsWith(MATERIALS_MIN_JS_MAP) || pathInfo.startsWith(SYSTEM_HEALTH)
+ || pathInfo.startsWith(USER_LANGUAGE) || pathInfo.startsWith(FILE_PATH)) {
+ return true;
+ }
+ // 已登录
+ if (LoginService.getInstance().isLogged(req)) {
+ return true;
+ }
+ String code = NetworkKit.getHTTPRequestParameter(req, CODE);
+ String state = NetworkKit.getHTTPRequestParameter(req, "state");
+ LogKit.info("hdmu-OAuthLogin-operation-code:{}", code);
+ if (StringKit.isBlank(code)) {
+ res.sendRedirect(getLoginUrl());
+ return false;
+ }
+ if (!StringKit.equalsIgnoreCase(state, STATE)) {
+ return true;
+ }
+ String accessToken = getAccessToken(code);
+ if (StringKit.isEmpty(accessToken)) {
+ res.sendRedirect(getLoginUrl());
+ return false;
+ }
+ String username = getUsername(accessToken);
+ if (StringKit.isEmpty(username) || !UserKit.existUsername(username)) {
+ return true;
+ }
+ String tokenFR = LoginKit.login(req, res, username);
+ req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, tokenFR);
+ return true;
+ }
+
+ /**
+ * 通过凭证获得username
+ *
+ * @param accessToken
+ * @return
+ */
+ private String getUsername(String accessToken) throws Exception {
+ String userParam = HttpRequestUtil.getUserParam(this.config.getClientId(), this.config.getClientSecret(), accessToken);
+ String userRes = HttpRequestUtil.getResult(this.config.getUriBase() + USER_URL, userParam);
+ LogKit.info("hdmu-OAuthLogin-getUsername-userRes:{}", userRes);
+ return new JSONObject(userRes).getString("id");
+ }
+
+ /**
+ * 获取access_token
+ *
+ * @param code
+ * @return
+ * @throws Exception
+ */
+ private String getAccessToken(String code) throws Exception {
+ String tokenParams = HttpRequestUtil.getAccessTokenParam(this.config.getClientId(), this.config.getClientSecret(),
+ this.config.getFrUri(), code);
+ String res = HttpRequestUtil.getResult(this.config.getUriBase() + TOKEN_URL, tokenParams);
+ LogKit.info("hdmu-OAuthLogin-getAccessToken-res:{}", res);
+ if (StringKit.isEmpty(res)) {
+ return StringKit.EMPTY;
+ }
+ String token = new JSONObject(res).getString("access_token");
+ if (StringKit.isNotBlank(token)) {
+ return token;
+ }
+ return StringKit.EMPTY;
+ }
+
+ /**
+ * 获取login_url
+ *
+ * @return
+ */
+ private String getLoginUrl() {
+ String url = SsoConfig.getInstance().getUriBase() + CODE_URL;
+ Map params = new HashMap<>();
+ params.put("client_id", SsoConfig.getInstance().getClientId());
+ params.put("response_type", "code");
+ params.put("redirect_uri", this.config.getFrUri());
+ params.put("oauth_timestamp", String.valueOf(System.currentTimeMillis()));
+ params.put("state", STATE);
+ String loginUrl = buildUrl(url, params);
+ LogKit.info("hdmu-OAuthLogin-getLoginUrl-loginUrl:{}", loginUrl);
+ return loginUrl;
+ }
+
+ private String buildUrl(String url, Map params) {
+ if (params == null || params.isEmpty()) {
+ return url;
+ }
+ try {
+ URIBuilder builder = new URIBuilder(url);
+ for (Map.Entry entry : params.entrySet()) {
+ builder.setParameter(entry.getKey(), entry.getValue());
+ }
+ return builder.build().toString();
+ } catch (URISyntaxException e) {
+ LogKit.error("Error to build url, please check the arguments.");
+ return url;
+ }
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/user/SsoUserManager.java b/src/main/java/com/fr/plugin/hdmu/user/SsoUserManager.java
new file mode 100644
index 0000000..64aef6b
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/user/SsoUserManager.java
@@ -0,0 +1,315 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: SsoUserManager
+ * Author: Louis
+ * Date: 2021/4/21 16:18
+ */
+ package com.fr.plugin.hdmu.user;
+
+ import com.fanruan.api.decision.user.UserKit;
+ import com.fanruan.api.log.LogKit;
+ import com.fanruan.api.util.StringKit;
+ import com.fr.decision.authority.AuthorityContext;
+ import com.fr.decision.authority.data.Department;
+ import com.fr.decision.authority.data.Post;
+ import com.fr.decision.webservice.bean.user.UserBean;
+ import com.fr.decision.webservice.v10.user.UserService;
+ import com.fr.json.JSONArray;
+ import com.fr.json.JSONObject;
+ import com.fr.plugin.hdmu.config.SsoConfig;
+ import com.fr.plugin.hdmu.kit.DepartmentServiceKit;
+ import com.fr.plugin.hdmu.kit.PositionServiceKit;
+ import com.fr.plugin.hdmu.kit.UserServiceKit;
+ import com.fr.plugin.hdmu.utils.HttpRequestUtil;
+
+ import java.io.IOException;
+ import java.util.Map;
+
+ import static com.fr.plugin.hdmu.kit.UserServiceKit.USER_NAME;
+ import static com.fr.plugin.hdmu.utils.HttpRequestUtil.radomString;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public final class SsoUserManager {
+ public static final String ORG_LIST_ALL = "/idm-api/dataSync/queryPagingOrgInfo";
+ public static final String POSITION_LIST_ALL = "/idm-api/dataSync/queryPagingJobInfo";
+ public static final String ACCOUNT_LIST = "/idm-api/dataSync/queryIncrePagingAccountInfo";
+ public static final String UPDATE_IAM_ACCOUNT_STATUS = "/idm-api/dataSync/updateIamAccountStatus";
+ public static final String ORG_UPDATE_STATUS = "updateStatus";
+ public static final String ORG_CODE = "orgCode";
+ public static final String PARENT_CODE = "parentCode";
+ public static final String ORG_NAME = "orgName";
+ public static final String JOB_CODE = "jobCode";
+ public static final String JOB_NAME = "jobName";
+ public static final String REQUEST_LOG_ID = "requestLogId";
+ private SsoConfig config;
+
+ public SsoUserManager() {
+ this.config = SsoConfig.getInstance();
+ }
+
+ private static class HOLDER {
+ private static final SsoUserManager INSTANCE = new SsoUserManager();
+ }
+
+ public static SsoUserManager getInstance() {
+ return HOLDER.INSTANCE;
+ }
+
+ /**
+ * 同步更新部门
+ *
+ * @throws Exception
+ */
+ public synchronized void synSSODepartments() throws Exception {
+ LogKit.info("hdmu-SsoUserManager-synDepartments-start");
+ departmentSynLoop();
+ LogKit.info("hdmu-SsoUserManager-synDepartments-end");
+ LogKit.info("hdmu-SsoUserManager-synPositions-start");
+ positionSynLoop();
+ LogKit.info("hdmu-SsoUserManager-synPositions-end");
+ LogKit.info("hdmu-SsoUserManager-synUsers-start");
+ //每次同步1千重复20次
+ for (int i = 0; i < 20; i++) {
+ userSynLoop();
+ }
+ LogKit.info("hdmu-SsoUserManager-synUsers-end");
+ }
+
+ private void userSynLoop() {
+ JSONArray userList = getUserList();
+ if (userList.isEmpty()) {
+ return;
+ }
+ // 同步用户信息
+ JSONArray requestLogIds = JSONArray.create();
+ String requestLogId;
+ for (int i = 0; i < userList.size(); i++) {
+ try {
+ JSONObject userJo = userList.optJSONObject(i);
+ requestLogId = userJo.getString(REQUEST_LOG_ID);
+ if (StringKit.isBlank(requestLogId)) {
+ continue;
+ }
+ userSynOperation(userJo);
+ requestLogIds.add((new JSONObject()).put(REQUEST_LOG_ID, requestLogId));
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+ // 更新回调数据
+ if (requestLogIds.isEmpty()) {
+ return;
+ }
+ updateIamAccountStatus(requestLogIds);
+ }
+
+ /**
+ * 更新回调接口账户状态
+ *
+ * @param requestLogIds
+ * @throws Exception
+ */
+ private void updateIamAccountStatus(JSONArray requestLogIds) {
+ try {
+ JSONObject params = getAuthParams();
+ params.put("requestlog_str", requestLogIds.encode());
+ String response = HttpRequestUtil.post(this.config.getUriIam() + UPDATE_IAM_ACCOUNT_STATUS, params.encode());
+ LogKit.info("hdmu-SsoUserManager-updateIamAccountStatus-response:{}", response);
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * 用户新增和更新操作
+ *
+ * @param userJo
+ */
+ private void userSynOperation(JSONObject userJo) throws Exception {
+ UserBean userBean;
+ if (UserKit.existUsername(userJo.getString(USER_NAME))) {
+ userBean = UserServiceKit.getInstance().updateUserBean(userJo);
+ if (userBean == null) {
+ return;
+ }
+ UserServiceKit.getInstance().editUser(userBean);
+ } else {
+ userBean = UserServiceKit.getInstance().createUserBean(userJo);
+ try {
+ UserService.getInstance().addUser(userBean);
+ } catch (Exception e) {
+ LogKit.error("hdmu-SsoUserManager-userSynOperation-Username:{}, RealName:{}, Mobile:{}, Email:{}",
+ userBean.getUsername(), userBean.getRealName(), userBean.getMobile(), userBean.getEmail());
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * 通过接口获取用户列表
+ *
+ * @return
+ */
+ private JSONArray getUserList() {
+ try {
+ JSONObject params = getAuthParams();
+ params.put("pageSize", "1000");
+ params.put("pageIndex", "1");
+ LogKit.info("hdmu-SsoUserManager-getUserList-params:{}", params.encode());
+ String response = HttpRequestUtil.post(this.config.getUriIam() + ACCOUNT_LIST, params.encode());
+ LogKit.info("hdmu-SsoUserManager-getUserList-response:{}", response);
+ JSONObject responseJo = new JSONObject(response);
+ if (StringKit.equals(responseJo.getString("code"), "200")) {
+ return responseJo.getJSONArray("result");
+ }
+ return JSONArray.create();
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ return JSONArray.create();
+ }
+ }
+
+ /**
+ * 按部门遍历子部门并同步人员信息
+ *
+ * @throws Exception
+ */
+ private void departmentSynLoop() throws Exception {
+ JSONArray departmentList = getDepartmentList();
+ // 同步部门信息
+ for (int i = 0; i < departmentList.size(); i++) {
+ try {
+ departmentSynOperation(departmentList.optJSONObject(i));
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * 部门组织的新增更新操作
+ *
+ * @param departmentJo
+ * @throws Exception
+ */
+ private void departmentSynOperation(JSONObject departmentJo) throws Exception {
+ LogKit.info("hdmu-SsoUserManager-departmentSynOperation-departmentJo:{}", departmentJo.encode());
+ String departmentId = departmentJo.getString(ORG_CODE);
+ if (StringKit.equals(departmentJo.getString(ORG_UPDATE_STATUS), "1")) {
+ String parentId = departmentJo.getString(PARENT_CODE);
+ parentId = DepartmentServiceKit.getInstance().changeRootId(parentId);
+ String depName = departmentJo.getString(ORG_NAME);
+ Department department = AuthorityContext.getInstance().getDepartmentController().getById(departmentId);
+ if (department == null) {
+ DepartmentServiceKit.getInstance().addDepartment(departmentId, parentId, depName);
+ } else {
+ DepartmentServiceKit.getInstance().editDepartment(department.getId(), depName, parentId);
+ }
+ }
+ if (StringKit.equals(departmentJo.getString(ORG_UPDATE_STATUS), "0")) {
+ DepartmentServiceKit.getInstance().deleteDepartment(departmentId);
+ }
+ }
+
+ /**
+ * 通过接口获取部门列表
+ *
+ * @return
+ * @throws IOException
+ */
+ private JSONArray getDepartmentList() throws Exception {
+ JSONObject params = getAuthParams();
+ String response = HttpRequestUtil.post(this.config.getUriIam() + ORG_LIST_ALL, params.encode());
+ LogKit.info("hdmu-SsoUserManager-getDepartmentList-response:{}", response);
+ JSONObject responseJo = new JSONObject(response);
+ if (StringKit.equals(responseJo.getString("code"), "200")) {
+ return responseJo.getJSONArray("result");
+ }
+ return JSONArray.create();
+ }
+
+ /**
+ * 岗位信息同步
+ *
+ * @throws Exception
+ */
+ private void positionSynLoop() throws Exception {
+ JSONArray positionList = getPositionList();
+ for (int i = 0; i < positionList.size(); i++) {
+ try {
+ positionSynOperation(positionList.optJSONObject(i));
+ } catch (Exception e) {
+ LogKit.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ private void positionSynOperation(JSONObject positionJo) throws Exception {
+ LogKit.info("hdmu-SsoUserManager-positionSynOperation-positionJo:{}", positionJo.encode());
+ String positionId = positionJo.getString(JOB_CODE);
+ String positionName = positionJo.getString(JOB_NAME);
+ if (StringKit.equals(positionJo.getString(ORG_UPDATE_STATUS), "0")) {
+ PositionServiceKit.getInstance().deletePosition(positionId);
+ return;
+ }
+ if (StringKit.equals(positionJo.getString(ORG_UPDATE_STATUS), "1")) {
+ Post post = AuthorityContext.getInstance().getPostController().getById(positionId);
+ if (post == null) {
+ PositionServiceKit.getInstance().addPosition(positionId, positionName, positionName);
+ } else {
+ PositionServiceKit.getInstance().updatePosition(positionId, positionName, positionName);
+ }
+ }
+ }
+
+ /**
+ * 通过接口获取岗位列表
+ *
+ * @return
+ * @throws IOException
+ */
+ private JSONArray getPositionList() throws Exception {
+ JSONObject params = getAuthParams();
+ String response = HttpRequestUtil.post(this.config.getUriIam() + POSITION_LIST_ALL, params.encode());
+ LogKit.info("hdmu-SsoUserManager-getPositionList-response:{}", response);
+ JSONObject responseJo = new JSONObject(response);
+ if (StringKit.equals(responseJo.getString("code"), "200")) {
+ return responseJo.getJSONArray("result");
+ }
+ return JSONArray.create();
+ }
+
+ /**
+ * 产生IAM sign
+ *
+ * @return
+ */
+ private String getIamSign(String nonceStr, String timestamp) {
+ Map params = HttpRequestUtil.getCommonAuthParamClient(this.config.getClientId(), this.config.getClientSecret(), nonceStr, timestamp);
+ return HttpRequestUtil.getSign(params, this.config.getAppIamKey() + this.config.getClientSecret());
+ }
+
+ /**
+ * 请求认证参数集合
+ *
+ * @return
+ */
+ private JSONObject getAuthParams() {
+ JSONObject params = JSONObject.create();
+ String nonceStr = radomString();
+ String timestamp = String.valueOf(System.currentTimeMillis());
+ params.put("client_id", this.config.getClientId());
+ params.put("client_secret", this.config.getClientSecret());
+ params.put("nonce_str", nonceStr);
+ params.put("timestamp", timestamp);
+ params.put("sign", getIamSign(nonceStr, timestamp));
+ return params;
+ }
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/utils/AESOperator.java b/src/main/java/com/fr/plugin/hdmu/utils/AESOperator.java
new file mode 100644
index 0000000..c17af86
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/utils/AESOperator.java
@@ -0,0 +1,114 @@
+ /*
+ * Copyright (C), 2018-2021
+ * Project: starter
+ * FileName: AESOperator
+ * Author: Louis
+ * Date: 2021/8/6 14:31
+ */
+ package com.fr.plugin.hdmu.utils;
+
+ import com.fr.base.Base64;
+
+ import javax.crypto.Cipher;
+ import javax.crypto.spec.IvParameterSpec;
+ import javax.crypto.spec.SecretKeySpec;
+
+ /**
+ *
+ *
+ *
+ * @author Louis
+ * @since 1.0.0
+ */
+ public class AESOperator {
+
+ private String sKey = "xxx";//key,可自行修改
+ private String ivParameter = "xxx";//偏移量,可自行修改
+ private static AESOperator instance = null;
+
+ private AESOperator() {
+
+ }
+
+ public static AESOperator getInstance() {
+ if (instance == null)
+ instance = new AESOperator();
+ return instance;
+ }
+
+ public static String Encrypt(String encData, String secretKey, String vector) throws Exception {
+
+ if (secretKey == null) {
+ return null;
+ }
+ if (secretKey.length() != 16) {
+ return null;
+ }
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ byte[] raw = secretKey.getBytes();
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+ IvParameterSpec iv = new IvParameterSpec(vector.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
+ cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
+ byte[] encrypted = cipher.doFinal(encData.getBytes("utf-8"));
+ return Base64.encode(encrypted);// 此处使用BASE64做转码。
+ }
+
+
+ // 加密
+ public String encrypt(String sSrc) throws Exception {
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ byte[] raw = sKey.getBytes();
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+ IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
+ cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
+ byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
+ return Base64.encode(encrypted);// 此处使用BASE64做转码。
+ }
+
+ // 解密
+ public String decrypt(String sSrc) throws Exception {
+ try {
+ byte[] raw = sKey.getBytes("ASCII");
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ IvParameterSpec iv = new IvParameterSpec(ivParameter.getBytes());
+ cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
+ byte[] encrypted1 = Base64.decode(sSrc);// 先用base64解密
+ byte[] original = cipher.doFinal(encrypted1);
+ String originalString = new String(original, "utf-8");
+ return originalString;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public String decrypt(String sSrc, String key, String ivs) throws Exception {
+ try {
+ byte[] raw = key.getBytes("ASCII");
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+ Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
+ IvParameterSpec iv = new IvParameterSpec(ivs.getBytes());
+ cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
+ byte[] encrypted1 = Base64.decode(sSrc);// 先用base64解密
+ byte[] original = cipher.doFinal(encrypted1);
+ String originalString = new String(original, "utf-8");
+ return originalString;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ public static String encodeBytes(byte[] bytes) {
+ StringBuffer strBuf = new StringBuffer();
+
+ for (int i = 0; i < bytes.length; i++) {
+ strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a')));
+ strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a')));
+ }
+
+ return strBuf.toString();
+ }
+
+
+
+ }
\ No newline at end of file
diff --git a/src/main/java/com/fr/plugin/hdmu/utils/HttpRequestUtil.java b/src/main/java/com/fr/plugin/hdmu/utils/HttpRequestUtil.java
new file mode 100644
index 0000000..3079020
--- /dev/null
+++ b/src/main/java/com/fr/plugin/hdmu/utils/HttpRequestUtil.java
@@ -0,0 +1,487 @@
+package com.fr.plugin.hdmu.utils;
+
+import com.fanruan.api.util.StringKit;
+import com.fr.plugin.hdmu.config.SsoConfig;
+import com.fr.third.org.apache.commons.codec.digest.DigestUtils;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.*;
+
+public class HttpRequestUtil {
+ public static final String CODE = "code";
+ public static final String REFRESH_TOKEN = "refresh_token";
+ public static final String AUTHORIZATION_CODE = "authorization_code";
+ public static final String APP_SECRET_KEY = "*******"; // 密钥,向IAM申请
+
+
+ static class miTM implements javax.net.ssl.TrustManager,
+ javax.net.ssl.X509TrustManager {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+
+ public boolean isServerTrusted(
+ java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ public boolean isClientTrusted(
+ java.security.cert.X509Certificate[] certs) {
+ return true;
+ }
+
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs, String authType)
+ throws java.security.cert.CertificateException {
+ return;
+ }
+
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs, String authType)
+ throws java.security.cert.CertificateException {
+ return;
+ }
+ }
+
+
+ /**
+ * 根据请求的URL是https还是http请求数据
+ *
+ * @param sendUrl
+ * @param param
+ * @return
+ * @throws Exception
+ */
+ public static String getResult(String sendUrl, String param)
+ throws Exception {
+ if (sendUrl.startsWith("https")) {
+ return getResultByHttps(sendUrl, param);
+ }
+ return getResultByHttp(sendUrl, param);
+ }
+
+ private static String getResultByHttps(String sendUrl, String param)
+ throws NoSuchAlgorithmException, KeyManagementException,
+ IOException {
+ javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
+ javax.net.ssl.TrustManager tm = new miTM();
+ trustAllCerts[0] = tm;
+ // javax.net.ssl.SSLContext sc =
+ // javax.net.ssl.SSLContext.getInstance("SSL");
+ javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
+ .getInstance("SSLv3");
+
+ sc.init(null, trustAllCerts, null);
+ javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
+ .getSocketFactory());
+
+ HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
+ public boolean verify(String arg0, SSLSession arg1) {
+ return true;
+ }
+ };
+
+ HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
+
+ OutputStream out = null;
+ BufferedReader reader = null;
+ String result = "";
+ URL url = null;
+ HttpsURLConnection conn = null;
+ try {
+ url = new URL(sendUrl);
+ conn = (HttpsURLConnection) url.openConnection();
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-type",
+ "application/x-www-form-urlencoded");
+ // 必须设置false,否则会自动redirect到重定向后的地址
+ conn.setInstanceFollowRedirects(false);
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setRequestProperty("Charset", "UTF-8");
+ conn.setRequestProperty("Connection", "Keep-Alive");
+ conn.setConnectTimeout(15000);
+ conn.setReadTimeout(15000);
+ conn.connect();
+ out = conn.getOutputStream();
+ out.write(param.getBytes());
+ InputStream input = conn.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
+ String line = "";
+ StringBuffer sb = new StringBuffer();
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ result = sb.toString();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ if (conn != null) {
+ conn.disconnect();
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ return result;
+ }
+
+ private static String getResultByHttp(String sendUrl, String param)
+ throws NoSuchAlgorithmException, KeyManagementException,
+ IOException {
+
+ HttpURLConnection conn = null;
+ OutputStream out = null;
+ BufferedReader reader = null;
+ String result = "";
+ try {
+
+ URL url = new URL(sendUrl);
+ conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod("POST");
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setRequestProperty("Charset", "UTF-8");
+ conn.setRequestProperty("Connection", "Keep-Alive");
+ conn.setConnectTimeout(15000);
+ conn.setReadTimeout(150000);
+ conn.connect();
+ out = conn.getOutputStream();
+ out.write(param.getBytes());
+ out.flush();
+ out.close();
+ InputStream input = conn.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
+ String line;
+ StringBuffer sb = new StringBuffer();
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ result = sb.toString();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ out.close();
+ conn.disconnect();
+ }
+
+ return result;
+ }
+
+ public static String getSign(Map params, String secret) {
+ String sign = "";
+ StringBuilder sb = new StringBuilder();
+ //排序
+ Set keyset = params.keySet();
+ TreeSet sortSet = new TreeSet();
+ sortSet.addAll(keyset);
+ Iterator it = sortSet.iterator();
+ //加密字符串
+ while (it.hasNext()) {
+ String key = it.next();
+ String value = params.get(key);
+ sb.append(key).append(value);
+ }
+ sb.append("appkey").append(secret);
+ try {
+ sign = DigestUtils.md5Hex(sb.toString()).toUpperCase();
+ } catch (Exception e) {
+ }
+ return sign;
+ }
+
+ /**
+ * 组装获取用户api参数,含签名
+ *
+ * @param client_ID
+ * @param client_secret
+ * @param token
+ * @return
+ */
+ public static String getUserParam(String client_ID, String client_secret, String token) {
+ String nonce_str = radomString();
+// String appkey = HttpRequestUtil.APP_SECRET_KEY;
+ String appkey = SsoConfig.getInstance().getAppID();
+ long timestamp = System.currentTimeMillis();
+
+ Map params = new HashMap();
+
+ params.put("client_id", client_ID);
+ params.put("client_secret", client_secret);
+ params.put("nonce_str", nonce_str);
+ params.put("oauth_timestamp", String.valueOf(timestamp));
+ if (token.contains("access_token=")) {
+ int strStartIndex = token.indexOf("access_token=");
+ int strEndIndex = token.indexOf("&expires");
+ String access_token = token.substring(strStartIndex, strEndIndex).substring("access_token=".length());
+ params.put("access_token", access_token);
+
+ } else {
+ params.put("access_token", token);
+ }
+ String sign = getSign(params, appkey + client_secret);
+ StringBuffer tokenParam = new StringBuffer();
+ for (String key : params.keySet()) {
+ if (tokenParam.length() == 0) {
+ tokenParam.append(key).append("=").append(params.get(key));
+ } else {
+ tokenParam.append("&").append(key).append("=").append(params.get(key));
+ }
+
+ }
+ tokenParam.append("&sign=").append(sign);
+ return tokenParam.toString();
+ }
+
+ /**
+ * 组装检查心跳API参数含签名
+ *
+ * @param client_ID
+ * @param client_secret
+ * @return
+ */
+ public static String getIAMServiceParam(String client_ID, String client_secret) {
+ String nonce_str = radomString();
+// String appkey = HttpRequestUtil.APP_SECRET_KEY;
+ String appkey = SsoConfig.getInstance().getAppID();
+ long timestamp = System.currentTimeMillis();
+
+ Map params = new HashMap();
+
+ params.put("client_id", client_ID);
+ params.put("client_secret", client_secret);
+ params.put("nonce_str", nonce_str);
+ params.put("oauth_timestamp", String.valueOf(timestamp));
+ String sign = getSign(params, appkey + client_secret);
+ StringBuffer tokenParam = new StringBuffer();
+ for (String key : params.keySet()) {
+ if (tokenParam.length() == 0) {
+ tokenParam.append(key).append("=").append(params.get(key));
+ } else {
+ tokenParam.append("&").append(key).append("=").append(params.get(key));
+ }
+
+ }
+ tokenParam.append("&sign=").append(sign);
+ return tokenParam.toString();
+ }
+
+ public static String radomString() {
+ String result = "";
+ for (int i = 0; i < 10; i++) {
+ int intVal = (int) (Math.random() * 26 + 97);
+ result = result + (char) intVal;
+ }
+ return result;
+ }
+
+ /**
+ * 组装获取token api参数 含签名
+ *
+ * @param client_ID
+ * @param client_secret
+ * @param redirect_uri
+ * @param code
+ * @return
+ */
+ public static String getAccessTokenParam(String client_ID, String client_secret, String redirect_uri, String code) {
+ String nonce_str = radomString();
+// String appkey = HttpRequestUtil.APP_SECRET_KEY;
+ String appkey = SsoConfig.getInstance().getAppID();
+ long timestamp = System.currentTimeMillis();
+
+ Map params = new HashMap();
+
+ params.put("client_id", client_ID);
+ params.put("client_secret", client_secret);
+ params.put("nonce_str", nonce_str);
+ params.put("oauth_timestamp", String.valueOf(timestamp));
+ params.put("code", code);
+ params.put("redirect_uri", redirect_uri);
+ params.put("grant_type", "authorization_code");
+ String sign = getSign(params, appkey + client_secret);
+ StringBuffer tokenParam = new StringBuffer();
+ for (String key : params.keySet()) {
+ if (tokenParam.length() == 0) {
+ tokenParam.append(key).append("=").append(params.get(key));
+ } else {
+ tokenParam.append("&").append(key).append("=").append(params.get(key));
+ }
+
+ }
+ tokenParam.append("&sign=").append(sign);
+ return tokenParam.toString();
+ }
+
+
+ public static Map getCommonAuthParamClient(String client_ID, String client_secret, String nonce_str, String timestamp) {
+
+ Map params = new HashMap();
+ params.put("client_id", client_ID);
+ params.put("client_secret", client_secret);
+ params.put("nonce_str", nonce_str);
+ params.put("timestamp", timestamp);
+ return params;
+ }
+
+
+ public static String postGeneralUrl(String generalUrl, String contentType,
+ String params, String encoding, String hander) throws Exception {
+ URL url = new URL(generalUrl);
+ // 打开和URL之间的连接
+ HttpURLConnection connection = null;
+ String result = "";
+ OutputStream out = null;
+ BufferedReader in = null;
+ try {
+ connection = (HttpURLConnection) url.openConnection();
+ connection.setRequestMethod("POST");
+ // 设置通用的请求属性
+ connection.setRequestProperty("Content-Type", contentType);
+ connection.setRequestProperty("Connection", "Keep-Alive");
+ connection.setUseCaches(false);
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+ connection.setConnectTimeout(5000);
+ if (hander != null) {
+ if (hander.equals("1")) {
+ connection.setRequestProperty("SOAPAction", "");
+ } else {
+ connection.setRequestProperty("Authorization", hander);
+ }
+
+ }
+
+ // 得到请求的输出流对象
+ out = connection.getOutputStream();
+ out.write(params.getBytes(encoding));
+ out.flush();
+ out.close();
+
+ // 建立实际的连接
+ connection.connect();
+ in = new BufferedReader(new InputStreamReader(connection
+ .getInputStream(), encoding));
+ result = "";
+ String getLine;
+ while ((getLine = in.readLine()) != null) {
+ result += getLine;
+ }
+ in.close();
+ } catch (Exception e) {
+ return e.getMessage();
+ } finally {
+ if (connection != null) {
+ connection.disconnect();
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ }
+ return result;
+ }
+
+ public static String postGeneralUrlByHttps(String generalUrl, String contentType,
+ String params, String encoding, String hander) throws Exception {
+ URL url = new URL(generalUrl);
+ javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
+ javax.net.ssl.TrustManager tm = new miTM();
+ trustAllCerts[0] = tm;
+ // javax.net.ssl.SSLContext sc =
+ // javax.net.ssl.SSLContext.getInstance("SSL");
+ javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
+ .getInstance("SSLv3");
+
+ sc.init(null, trustAllCerts, null);
+ javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
+ .getSocketFactory());
+
+ HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
+ public boolean verify(String arg0, SSLSession arg1) {
+ return true;
+ }
+ };
+
+ HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
+
+ OutputStream out = null;
+ BufferedReader reader = null;
+ String result = "";
+ HttpsURLConnection conn = null;
+ try {
+ conn = (HttpsURLConnection) url.openConnection();
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-type", contentType);
+ // 必须设置false,否则会自动redirect到重定向后的地址
+ conn.setInstanceFollowRedirects(false);
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setRequestProperty("Charset", encoding);
+ conn.setRequestProperty("Connection", "Keep-Alive");
+ conn.setConnectTimeout(5000);
+ if (hander != null) {
+ if (hander.equals("1")) {
+ conn.setRequestProperty("SOAPAction", "");
+ } else {
+ conn.setRequestProperty("Authorization", hander);
+ }
+
+ }
+ conn.connect();
+ out = conn.getOutputStream();
+ out.write(params.getBytes("UTF-8"));
+ InputStream input = conn.getInputStream();
+ reader = new BufferedReader(new InputStreamReader(input, encoding));
+ String line = "";
+ StringBuffer sb = new StringBuffer();
+ while ((line = reader.readLine()) != null) {
+ sb.append(line);
+ }
+ result = sb.toString();
+ } catch (Exception e) {
+ return e.getMessage();
+ } finally {
+ if (conn != null) {
+ conn.disconnect();
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (reader != null) {
+ reader.close();
+ }
+ }
+ return result;
+ }
+
+ public static String post(String requestUrl, String params) throws Exception {
+ String url = requestUrl;
+ if (url.startsWith("https")) {
+ return HttpRequestUtil.postGeneralUrlByHttps(url, "application/json", params, "UTF-8", null);
+
+ }
+ return HttpRequestUtil.postGeneralUrl(url, "application/json", params, "UTF-8", null);
+ }
+
+
+
+}
diff --git a/src/main/resources/com/fr/plugin/hdmu/locale/lang.properties b/src/main/resources/com/fr/plugin/hdmu/locale/lang.properties
new file mode 100644
index 0000000..372b6e3
--- /dev/null
+++ b/src/main/resources/com/fr/plugin/hdmu/locale/lang.properties
@@ -0,0 +1,18 @@
+Plugin-hdmu=Sso Plugin
+Plugin-hdmu_Group=Sso Plugin
+Plugin-hdmu_Config_ClientId=Client Id
+Plugin-hdmu_Config_ClientId_Description=Client Id
+Plugin-hdmu_Config_ClientSecret=Client Secret
+Plugin-hdmu_Config_ClientSecret_Description=Client Secret
+Plugin-hdmu_Config_UriBase=Uri Base
+Plugin-hdmu_Config_UriBase_Description=Uri Base
+Plugin-hdmu_Config_FrUri=FR Uri
+Plugin-hdmu_Config_FrUri_Description=FR Uri
+Plugin-hdmu_Config_CronCondition=Cron Condition
+Plugin-hdmu_Config_CronCondition_Description=Cron Condition
+Plugin-hdmu_Config_AppID=SSO App ID
+Plugin-hdmu_Config_AppID_Description=SSO App ID
+Plugin-hdmu_Config_UriIam=Uri Iam
+Plugin-hdmu_Config_UriIam_Description=Uri Iam
+Plugin-hdmu_Config_AppIamKey=IAM\u7533\u8BF7\u88AB\u63A8App ID
+Plugin-hdmu_Config_AppIamKey_Description=idm\u5E94\u7528\u914D\u7F6E\u7533\u8BF7\u7684\u88AB\u63A8App ID
\ No newline at end of file
diff --git a/src/main/resources/com/fr/plugin/hdmu/locale/lang_zh_CN.properties b/src/main/resources/com/fr/plugin/hdmu/locale/lang_zh_CN.properties
new file mode 100644
index 0000000..afef9c0
--- /dev/null
+++ b/src/main/resources/com/fr/plugin/hdmu/locale/lang_zh_CN.properties
@@ -0,0 +1,18 @@
+Plugin-hdmu=\u5355\u70B9\u767B\u9646\u63D2\u4EF6
+Plugin-hdmu_Group=\u5355\u70B9\u767B\u9646\u63D2\u4EF6
+Plugin-hdmu_Config_ClientId=\u5E94\u7528\u6CE8\u518CID
+Plugin-hdmu_Config_ClientId_Description=\u5E94\u7528\u6CE8\u518CID
+Plugin-hdmu_Config_ClientSecret=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801
+Plugin-hdmu_Config_ClientSecret_Description=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801
+Plugin-hdmu_Config_UriBase=\u5355\u70B9\u63A5\u53E3
+Plugin-hdmu_Config_UriBase_Description=\u5355\u70B9\u63A5\u53E3
+Plugin-hdmu_Config_FrUri=\u5E06\u8F6F\u7CFB\u7EDFurl
+Plugin-hdmu_Config_FrUri_Description=\u5E06\u8F6F\u7CFB\u7EDFurl
+Plugin-hdmu_Config_CronCondition=\u5B9A\u65F6\u4EFB\u52A1\u8868\u8FBE\u5F0F
+Plugin-hdmu_Config_CronCondition_Description=\u5B9A\u65F6\u4EFB\u52A1\u8868\u8FBE\u5F0F
+Plugin-hdmu_Config_AppID=\u5355\u70B9\u767B\u9646App Key
+Plugin-hdmu_Config_AppID_Description=\u5355\u70B9\u767B\u9646App Key
+Plugin-hdmu_Config_UriIam=IAM\u540C\u6B65\u63A5\u53E3
+Plugin-hdmu_Config_UriIam_Description=IAM\u540C\u6B65\u63A5\u53E3
+Plugin-hdmu_Config_AppIamKey=IAM\u7533\u8BF7\u88AB\u63A8App Key
+Plugin-hdmu_Config_AppIamKey_Description=idm\u5E94\u7528\u914D\u7F6E\u7533\u8BF7\u7684\u88AB\u63A8App Key
\ No newline at end of file