LAPTOP-SB56SG4Q\86185
3 years ago
22 changed files with 1423 additions and 1 deletions
Binary file not shown.
Binary file not shown.
@ -1,3 +1,6 @@
|
||||
# open-JSD-7508 |
||||
|
||||
JSD-7508 OAuth2 + 组织&用户同步 |
||||
JSD-7508 OAuth2 + 组织&用户同步\ |
||||
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<plugin> |
||||
<id>com.fr.plugin.j7508.sso.auth</id> |
||||
<name><![CDATA[jsd7508-单点登陆]]></name> |
||||
<active>yes</active> |
||||
<version>1.1.3</version> |
||||
<env-version>10.0</env-version> |
||||
<jartime>2018-07-31</jartime> |
||||
<vendor>fr.open</vendor> |
||||
<description><![CDATA[单点登陆jsd7508]]></description> |
||||
<change-notes><![CDATA[单点登陆jsd7508]]></change-notes> |
||||
<main-package>com.fr.plugin.j7508.sso</main-package> |
||||
<prefer-packages> |
||||
<prefer-package>com.fanruan.api</prefer-package> |
||||
</prefer-packages> |
||||
<lifecycle-monitor class="com.fr.plugin.j7508.sso.PluginMonitor"/> |
||||
<extra-core> |
||||
<LocaleFinder class="com.fr.plugin.j7508.sso.LocaleFinder"/> |
||||
</extra-core> |
||||
<extra-decision> |
||||
<ControllerRegisterProvider class="com.fr.plugin.j7508.sso.request.UserControllerBridge"/> |
||||
<GlobalRequestFilterProvider class="com.fr.plugin.j7508.sso.request.OAuthLogin"/> |
||||
</extra-decision> |
||||
<function-recorder class="com.fr.plugin.j7508.sso.LocaleFinder"/> |
||||
</plugin> |
@ -0,0 +1,37 @@
|
||||
/* |
||||
* Copyright (C), 2018-2020 |
||||
* Project: starter |
||||
* FileName: LocaleFinder |
||||
* Author: Louis |
||||
* Date: 2020/8/31 22:19 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso; |
||||
|
||||
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.j7508.sso.config.SsoConfig.PLUGIN_ID; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <LocaleFinder> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@EnableMetrics |
||||
public class LocaleFinder extends AbstractLocaleFinder { |
||||
|
||||
@Override |
||||
@Focus(id = PLUGIN_ID, text = "Plugin-J7508-Sso", source = Original.PLUGIN) |
||||
public String find() { |
||||
return "com/fr/plugin/j7508/sso/locale/lang"; |
||||
} |
||||
|
||||
@Override |
||||
public int currentAPILevel() { |
||||
return CURRENT_LEVEL; |
||||
} |
||||
} |
@ -0,0 +1,49 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: PluginMonitor |
||||
* Author: Louis |
||||
* Date: 2021/3/30 15:10 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso; |
||||
|
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fr.plugin.context.PluginContext; |
||||
import com.fr.plugin.j7508.sso.config.SsoConfig; |
||||
import com.fr.plugin.j7508.sso.helper.SsoUserScheduleHelper; |
||||
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||
|
||||
import static com.fr.plugin.j7508.sso.helper.SsoUserScheduleHelper.SSO_USER_SCHEDULE_SYN_MEMBER_GROUP; |
||||
import static com.fr.plugin.j7508.sso.helper.SsoUserScheduleHelper.SSO_USER_SCHEDULE_SYN_MEMBER_JOB_NAME; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <PluginMonitor> |
||||
* |
||||
* @author fr.open |
||||
* @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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,99 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: DataResponse |
||||
* Author: Louis |
||||
* Date: 2021/3/19 11:46 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.bean; |
||||
|
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.decision.webservice.Response; |
||||
import com.fr.third.fasterxml.jackson.annotation.JsonInclude; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <DataResponse> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@JsonInclude(JsonInclude.Include.NON_DEFAULT) |
||||
public class DataResponse extends Response { |
||||
private static final long serialVersionUID = -6046189959382243612L; |
||||
private String timestamp; |
||||
private String code; |
||||
private String msg; |
||||
|
||||
public DataResponse() { |
||||
} |
||||
|
||||
private static DataResponse create() { |
||||
return new DataResponse(); |
||||
} |
||||
|
||||
/** |
||||
* 相应success结果 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static DataResponse success() { |
||||
return create().code("0").timeStamp(String.valueOf(System.currentTimeMillis())).message("success"); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 报错结果 |
||||
* |
||||
* @param code |
||||
* @param message |
||||
* @return |
||||
*/ |
||||
public static DataResponse error(String code, String message) { |
||||
return create().code(code).message(message).data(StringKit.EMPTY); |
||||
} |
||||
|
||||
public DataResponse timeStamp(String timeStamp) { |
||||
this.timestamp = timeStamp; |
||||
return this; |
||||
} |
||||
|
||||
public DataResponse code(String code) { |
||||
this.code = code; |
||||
return this; |
||||
} |
||||
|
||||
public DataResponse message(String message) { |
||||
this.msg = message; |
||||
return this; |
||||
} |
||||
|
||||
public DataResponse data(Object data) { |
||||
this.setData(data); |
||||
return this; |
||||
} |
||||
|
||||
public String getTimestamp() { |
||||
return timestamp; |
||||
} |
||||
|
||||
public void setTimestamp(String timestamp) { |
||||
this.timestamp = timestamp; |
||||
} |
||||
|
||||
public String getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public void setCode(String code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public String getMsg() { |
||||
return msg; |
||||
} |
||||
|
||||
public void setMsg(String msg) { |
||||
this.msg = msg; |
||||
} |
||||
} |
@ -0,0 +1,107 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: SsoUserJobConstructor |
||||
* Author: Louis |
||||
* Date: 2021/4/21 15:58 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.bean; |
||||
|
||||
import com.fr.scheduler.job.FineScheduleJob; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <SsoUserJobConstructor> |
||||
* |
||||
* @author fr.open |
||||
* @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; |
||||
} |
||||
} |
@ -0,0 +1,122 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: OneAccessConfig |
||||
* Author: Louis |
||||
* Date: 2021/3/30 9:38 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.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; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <SsoConfig> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@Visualization(category = "Plugin-J7508-Sso_Group") |
||||
public class SsoConfig extends DefaultConfiguration { |
||||
public static final String PLUGIN_ID = "com.fr.plugin.j7508.sso.auth"; |
||||
public static final String BASE_URI = "xxxx"; |
||||
public static final String ESB_URI = "xxxx"; |
||||
// 每天中午十二点触发
|
||||
public static final String CRON_CONDITION = "0 0 12 * * ?"; |
||||
|
||||
private static volatile SsoConfig config = null; |
||||
|
||||
@Focus(id = PLUGIN_ID, text = "Plugin-J7508-Sso", source = Original.PLUGIN) |
||||
public static SsoConfig getInstance() { |
||||
if (config == null) { |
||||
config = ConfigContext.getConfigInstance(SsoConfig.class); |
||||
} |
||||
return config; |
||||
} |
||||
|
||||
@Identifier(value = "frUri", name = "Plugin-J7508-Sso_Config_FrUri", description = "Plugin-J7508-Sso_Config_FrUri_Description", status = Status.SHOW) |
||||
private Conf<String> frUri = Holders.simple(StringKit.EMPTY); |
||||
@Identifier(value = "uriBase", name = "Plugin-J7508-Sso_Config_UriBase", description = "Plugin-J7508-Sso_Config_UriBase_Description", status = Status.SHOW) |
||||
private Conf<String> uriBase = Holders.simple(BASE_URI); |
||||
@Identifier(value = "esbUri", name = "Plugin-J7508-Sso_Config_EsbUri", description = "Plugin-J7508-Sso_Config_EsbUri_Description", status = Status.SHOW) |
||||
private Conf<String> esbUri = Holders.simple(ESB_URI); |
||||
@Identifier(value = "clientId", name = "Plugin-J7508-Sso_Config_ClientId", description = "Plugin-J7508-Sso_Config_ClientId_Description", status = Status.SHOW) |
||||
private Conf<String> clientId = Holders.simple(StringKit.EMPTY); |
||||
@Identifier(value = "clientSecret", name = "Plugin-J7508-Sso_Config_ClientSecret", description = "Plugin-J7508-Sso_Config_ClientSecret_Description", status = Status.SHOW) |
||||
private Conf<String> clientSecret = Holders.simple(StringKit.EMPTY); |
||||
@Identifier(value = "cronCondition", name = "Plugin-J7508-Sso_Config_CronCondition", description = "Plugin-J7508-Sso_Config_CronCondition_Description", status = Status.SHOW) |
||||
private Conf<String> cronCondition = Holders.simple(CRON_CONDITION); |
||||
@Identifier(value = "appID", name = "Plugin-J7508-Sso_Config_AppID", description = "Plugin-J7508-Sso_Config_AppID_Description", status = Status.SHOW) |
||||
private Conf<String> appID = Holders.simple(StringKit.EMPTY); |
||||
@Identifier(value = "appSecret", name = "Plugin-J7508-Sso_Config_AppSecret", description = "Plugin-J7508-Sso_Config_AppSecret_Description", status = Status.SHOW) |
||||
private Conf<String> appSecret = Holders.simple(StringKit.EMPTY); |
||||
|
||||
public String getFrUri() { |
||||
return frUri.get(); |
||||
} |
||||
|
||||
public void setFrUri(String frUri) { |
||||
this.frUri.set(frUri); |
||||
} |
||||
|
||||
public String getUriBase() { |
||||
return uriBase.get(); |
||||
} |
||||
|
||||
public void setUriBase(String uriBase) { |
||||
this.uriBase.set(uriBase); |
||||
} |
||||
|
||||
public String getEsbUri() { |
||||
return esbUri.get(); |
||||
} |
||||
|
||||
public void setEsbUri(String esbUri) { |
||||
this.esbUri.set(esbUri); |
||||
} |
||||
|
||||
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 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 getAppSecret() { |
||||
return appSecret.get(); |
||||
} |
||||
|
||||
public void setAppSecret(String appSecret) { |
||||
this.appSecret.set(appSecret); |
||||
} |
||||
} |
@ -0,0 +1,77 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: DingTalkScheduleHelper |
||||
* Author: Louis |
||||
* Date: 2021/4/21 15:52 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.helper; |
||||
|
||||
import com.fr.plugin.j7508.sso.bean.SsoUserJobConstructor; |
||||
import com.fr.plugin.j7508.sso.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; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <DingTalkScheduleHelper> |
||||
* |
||||
* @author fr.open |
||||
* @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 SsoUserScheduleHelper.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() { |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,34 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: SsoUserSyncMemberJob |
||||
* Author: Louis |
||||
* Date: 2021/4/21 16:02 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.job; |
||||
|
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fr.cluster.core.ClusterNode; |
||||
import com.fr.plugin.j7508.sso.user.SsoUserManager; |
||||
import com.fr.scheduler.job.FineScheduleJob; |
||||
import com.fr.third.v2.org.quartz.JobExecutionContext; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <SsoUserSyncMemberJob> |
||||
* |
||||
* @author fr.open |
||||
* @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); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,96 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: DepartmentServiceKit |
||||
* Author: Louis |
||||
* Date: 2021/5/14 9:38 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.kit; |
||||
|
||||
import com.fanruan.api.i18n.I18nKit; |
||||
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.record.OperateMessage; |
||||
import com.fr.decision.webservice.exception.general.DuplicatedNameException; |
||||
import com.fr.decision.webservice.v10.user.DepartmentService; |
||||
import com.fr.general.ComparatorUtils; |
||||
import com.fr.intelli.record.MetricRegistry; |
||||
import com.fr.stable.StableUtils; |
||||
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 java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
import static com.fr.decision.authority.base.AuthorityConstants.DECISION_DEP_ROOT; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <DepartmentServiceKit> |
||||
* |
||||
* @author fr.open |
||||
* @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; |
||||
} |
||||
|
||||
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); |
||||
MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-Department", this.getDepartmentFullPath(pId, depName, "/"), "Dec-Log_Add")); |
||||
} |
||||
|
||||
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(); |
||||
} |
||||
} |
||||
|
||||
private String getDepartmentFullPath(String pId, String depName, String splitter) throws Exception { |
||||
List<String> paths = new ArrayList<>(); |
||||
paths.add(depName); |
||||
while (!ComparatorUtils.equals(pId, DECISION_DEP_ROOT) && pId != null) { |
||||
Department parentDepartment = AuthorityContext.getInstance().getDepartmentController().getById(pId); |
||||
paths.add(parentDepartment.getName()); |
||||
pId = parentDepartment.getParentId(); |
||||
} |
||||
Collections.reverse(paths); |
||||
return StableUtils.join(paths.toArray(new String[0]), splitter); |
||||
} |
||||
|
||||
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); |
||||
String departmentFullPath = DepartmentService.getInstance().getDepartmentFullPath(departmentId); |
||||
if (!ComparatorUtils.equals(department.getName(), depName)) { |
||||
this.checkDuplicatedDepartmentName(department.getParentId(), depName); |
||||
department.setName(depName); |
||||
department.setParentId(pId); |
||||
AuthorityContext.getInstance().getDepartmentController().update(department); |
||||
} |
||||
MetricRegistry.getMetric().submit(OperateMessage.build("Dec-Module-User_Manager", "Dec-Department", DepartmentService.getInstance().getDepartmentFullPath(departmentId), "Dec-Log_Update", I18nKit.getLocText("Fine-Dec_Department") + ":" + departmentFullPath)); |
||||
} |
||||
} |
@ -0,0 +1,169 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: UserServiceKit |
||||
* Author: Louis |
||||
* Date: 2021/5/14 8:28 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.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.Post; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.authority.data.personnel.DepRole; |
||||
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.utils.UserSourceFactory; |
||||
import com.fr.decision.webservice.utils.WebServiceUtils; |
||||
import com.fr.decision.webservice.v10.user.PositionService; |
||||
import com.fr.decision.webservice.v10.user.UserService; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.stable.collections.CollectionUtils; |
||||
import com.fr.stable.query.QueryFactory; |
||||
import com.fr.stable.query.restriction.RestrictionFactory; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <UserServiceKit> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class UserServiceKit extends UserService { |
||||
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("uid")); |
||||
userBean.setRealName(account.getString("userName")); |
||||
userBean.setEnable(StringKit.equals(account.getString("status"), "1")); |
||||
userBean.setEmail(account.getString("email")); |
||||
userBean.setMobile(account.getString("mobile")); |
||||
userBean.setPassword(TransmissionTool.defaultEncrypt(account.getString("uid") + "123456")); |
||||
if (StringKit.isNotBlank(account.getString("orgCode"))) { |
||||
List<String> departmentPostIds = createDepartmentPostIds(account.getString("orgCode"), account.getString("jobTitle")); |
||||
userBean.setDepartmentPostIds(departmentPostIds); |
||||
} |
||||
return userBean; |
||||
} |
||||
|
||||
/** |
||||
* 转为部门职务组合 |
||||
* |
||||
* @param departmentPostId |
||||
* @param title |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
private List<String> createDepartmentPostIds(String departmentPostId, String title) throws Exception { |
||||
List<String> departmentPostIds = new ArrayList<>(); |
||||
if (StringKit.isBlank(departmentPostId) || StringKit.equals(departmentPostId, "null")) { |
||||
return departmentPostIds; |
||||
} |
||||
String positionId = positionSynOperation(title, departmentPostId); |
||||
if (StringKit.isNotBlank(positionId)) { |
||||
departmentPostId = departmentPostId + "@@@" + positionId; |
||||
} |
||||
departmentPostIds.add(departmentPostId); |
||||
return departmentPostIds; |
||||
} |
||||
|
||||
/** |
||||
* 职务同步操作 |
||||
* |
||||
* @param title |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
private String positionSynOperation(String title, String departmentId) throws Exception { |
||||
String position = StringKit.isNotBlank(title) ? title : "职员"; |
||||
Post post = AuthorityContext.getInstance().getPostController().findOne(QueryFactory.create().addRestriction(RestrictionFactory.eq("name", position))); |
||||
String positionId; |
||||
if (post == null) { |
||||
positionId = PositionService.getInstance().addPosition(position, position); |
||||
} else { |
||||
positionId = post.getId(); |
||||
} |
||||
List<DepartmentPostBean> departmentPostBeanList = PositionService.getInstance().getPositionsUnderParentDepartment(getAdminUserId(), departmentId, position); |
||||
if (departmentPostBeanList == null || departmentPostBeanList.isEmpty()) { |
||||
try { |
||||
AuthorityContext.getInstance().getPostController().addPostToDepartment(positionId, departmentId); |
||||
} catch (Exception e) { |
||||
LogKit.info("sso-UserServiceKit-positionSynOperation-addPostToDepartmentFailed-position:{}, departmentId:{}", positionId + position, departmentId); |
||||
LogKit.error(e.getMessage(), e); |
||||
} |
||||
} |
||||
return positionId; |
||||
} |
||||
|
||||
/** |
||||
* 获取管理员id |
||||
* |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
public String getAdminUserId() throws Exception { |
||||
List<String> adminUserIdList = UserService.getInstance().getAdminUserIdList(); |
||||
if (adminUserIdList.isEmpty()) { |
||||
return "admin"; |
||||
} |
||||
return StringKit.isNotBlank(adminUserIdList.get(0)) ? adminUserIdList.get(0) : "admin"; |
||||
} |
||||
|
||||
public UserBean updateUserBean(JSONObject account) throws Exception { |
||||
User user = UserService.getInstance().getUserByUserName(account.getString("uid")); |
||||
if (user == null) { |
||||
return null; |
||||
} |
||||
UserBean userBean = new UserBean(); |
||||
userBean.setId(user.getId()); |
||||
userBean.setUsername(user.getUserName()); |
||||
userBean.setRealName(account.getString("userName")); |
||||
userBean.setEnable(StringKit.equals(account.getString("status"), "1")); |
||||
userBean.setEmail(account.getString("email")); |
||||
userBean.setMobile(account.getString("mobile")); |
||||
if (StringKit.isNotBlank(account.getString("orgCode"))) { |
||||
List<String> departmentPostIds = createDepartmentPostIds(account.getString("orgCode"), account.getString("jobTitle")); |
||||
userBean.setDepartmentPostIds(departmentPostIds); |
||||
} |
||||
return userBean; |
||||
} |
||||
|
||||
/** |
||||
* 增加用户部门关联 |
||||
* |
||||
* @param userBean |
||||
* @throws Exception |
||||
*/ |
||||
public void addUserDepartment(UserBean userBean) throws Exception { |
||||
if (CollectionUtils.isEmpty(userBean.getDepartmentPostIds())) { |
||||
return; |
||||
} |
||||
for (String departmentPostId : userBean.getDepartmentPostIds()) { |
||||
if (StringUtils.isEmpty(departmentPostId)) { |
||||
continue; |
||||
} |
||||
User user = UserService.getInstance().getUserByUserName(userBean.getUsername()); |
||||
DepRole depRole = WebServiceUtils.parseUniqueDepartmentPostId(departmentPostId); |
||||
UserSourceFactory.getInstance().checkSource(user, AuthorityContext.getInstance().getDepartmentController().getById(depRole.getDepartmentId())); |
||||
AuthorityContext.getInstance().getUserController().addUserToDepartmentAndPost(user.getId(), depRole.getDepartmentId(), depRole.getPostId()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,221 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: OAuthLogin |
||||
* Author: Louis |
||||
* Date: 2021/3/30 22:09 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.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.net.http.HttpKit; |
||||
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.j7508.sso.config.SsoConfig; |
||||
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.io.IOException; |
||||
import java.net.URISyntaxException; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <OAuthLogin> |
||||
* |
||||
* @author fr.open |
||||
* @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 ACCOUNT_IAMPUSH = "/account/iamPush"; |
||||
|
||||
public static final String CODE_URL = "/esc-sso/oauth2.0/authorize"; |
||||
public static final String TOKEN_URL = "/esc-sso/oauth2.0/accessToken"; |
||||
public static final String USER_URL = "/esc-sso/oauth2.0/profile"; |
||||
public static final String CODE = "code"; |
||||
|
||||
private SsoConfig config; |
||||
|
||||
/** |
||||
* 过滤器名称 |
||||
* |
||||
* @return |
||||
*/ |
||||
@Override |
||||
public String filterName() { |
||||
return "J7508Filter"; |
||||
} |
||||
|
||||
/** |
||||
* 过滤规则 |
||||
* |
||||
* @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; |
||||
LogKit.info("sso-OAuthLogin-operation-pathInfo:{}", pathInfo); |
||||
if (pathInfo.startsWith(REMOTE_DESIGN) || pathInfo.startsWith(LOGIN_OTHER) |
||||
|| StringKit.equals(LOGIN_PATH, pathInfo) || StringKit.equals(ACCOUNT_IAMPUSH, pathInfo) |
||||
|| pathInfo.startsWith(RESOURCES_PATH) || pathInfo.startsWith(LOGOUT_PATH) |
||||
|| pathInfo.startsWith(SYSTEM_INFO) || pathInfo.startsWith(MATERIALS_MIN_JS_MAP) |
||||
|| pathInfo.startsWith(USER_LANGUAGE) || pathInfo.startsWith(FILE_PATH)) { |
||||
return true; |
||||
} |
||||
// 已登录
|
||||
if (LoginService.getInstance().isLogged(req)) { |
||||
return true; |
||||
} |
||||
String code = NetworkKit.getHTTPRequestParameter(req, CODE); |
||||
LogKit.info("sso-OAuthLogin-operation-code:{}", code); |
||||
if (StringKit.isBlank(code)) { |
||||
res.sendRedirect(getLoginUrl(req)); |
||||
return false; |
||||
} |
||||
String accessToken = getAccessToken(code); |
||||
if (StringKit.isEmpty(accessToken)) { |
||||
res.sendRedirect(getLoginUrl(req)); |
||||
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 IOException { |
||||
Map<String, String> userInfoParams = new HashMap<>(); |
||||
userInfoParams.put("access_token", accessToken); |
||||
String userRes = HttpKit.get(this.config.getUriBase() + USER_URL, userInfoParams); |
||||
LogKit.info("sso-OAuthLogin-getUsername-userRes:{}", userRes); |
||||
return new JSONObject(userRes).getString("id"); |
||||
} |
||||
|
||||
/** |
||||
* 获取access_token |
||||
* |
||||
* @param code |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
private String getAccessToken(String code) throws Exception { |
||||
Map<String, String> params = new HashMap<>(); |
||||
params.put("grant_type", "authorization_code"); |
||||
params.put("oauth_timestamp", String.valueOf(System.currentTimeMillis())); |
||||
params.put("client_id", this.config.getClientId()); |
||||
params.put("client_secret", this.config.getClientSecret()); |
||||
params.put("code", code); |
||||
params.put("redirect_uri", this.config.getFrUri()); |
||||
String url = this.config.getUriBase() + TOKEN_URL; |
||||
String res = HttpKit.post(url, params); |
||||
LogKit.info("sso-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(HttpServletRequest request) { |
||||
String url = SsoConfig.getInstance().getUriBase() + CODE_URL; |
||||
Map<String, String> params = new HashMap<>(); |
||||
params.put("client_id", SsoConfig.getInstance().getClientId()); |
||||
params.put("response_type", "code"); |
||||
params.put("redirect_uri", this.config.getFrUri()); |
||||
String loginUrl = buildUrl(url, params); |
||||
LogKit.info("sso-OAuthLogin-getLoginUrl-loginUrl:{}", loginUrl); |
||||
return loginUrl; |
||||
} |
||||
|
||||
private String buildUrl(String url, Map<String, String> params) { |
||||
if (params == null || params.isEmpty()) { |
||||
return url; |
||||
} |
||||
try { |
||||
URIBuilder builder = new URIBuilder(url); |
||||
for (Map.Entry<String, String> entry : params.entrySet()) { |
||||
builder.setParameter(entry.getKey(), entry.getValue()); |
||||
} |
||||
return builder.build().toString(); |
||||
} catch (URISyntaxException e) { |
||||
LogKit.debug("Error to build url, please check the arguments."); |
||||
return url; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,26 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: UserControllerBridge |
||||
* Author: Louis |
||||
* Date: 2021/3/29 22:30 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.request; |
||||
|
||||
import com.fr.decision.fun.impl.AbstractControllerRegisterProvider; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <UserControllerBridge> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public class UserControllerBridge extends AbstractControllerRegisterProvider { |
||||
@Override |
||||
public Class[] getControllers() { |
||||
return new Class[]{ |
||||
UserPushController.class |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,120 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: UserPushController |
||||
* Author: Louis |
||||
* Date: 2021/3/29 22:36 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.request; |
||||
|
||||
import com.fanruan.api.decision.user.UserKit; |
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fr.decision.authority.data.User; |
||||
import com.fr.decision.webservice.annotation.LoginStatusChecker; |
||||
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.j7508.sso.bean.DataResponse; |
||||
import com.fr.plugin.j7508.sso.config.SsoConfig; |
||||
import com.fr.plugin.j7508.sso.kit.UserServiceKit; |
||||
import com.fr.third.springframework.stereotype.Controller; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestBody; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMapping; |
||||
import com.fr.third.springframework.web.bind.annotation.RequestMethod; |
||||
import com.fr.third.springframework.web.bind.annotation.ResponseBody; |
||||
|
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <UserPushController> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
@Controller |
||||
@RequestMapping("account/iamPush") |
||||
public class UserPushController { |
||||
private SsoConfig config; |
||||
private String adminName; |
||||
|
||||
public UserPushController() { |
||||
this.config = SsoConfig.getInstance(); |
||||
} |
||||
|
||||
@RequestMapping(method = RequestMethod.POST) |
||||
@ResponseBody |
||||
@LoginStatusChecker(required = false) |
||||
public DataResponse doAction(@RequestBody(required = false) String bodyContent, HttpServletResponse res) { |
||||
try { |
||||
LogKit.info("sso-UserPushController-doAction-bodyContent:{}", bodyContent); |
||||
JSONObject bodyJson = new JSONObject(bodyContent); |
||||
JSONArray accounts = bodyJson.getJSONArray("data"); |
||||
this.adminName = UserService.getInstance().getAdminUserNameList().get(0); |
||||
setHeader(res); |
||||
operation(accounts); |
||||
return DataResponse.success(); |
||||
} catch (Exception e) { |
||||
LogKit.error(e.getMessage(), e); |
||||
return DataResponse.error("1", "error"); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 企业应用业务事件处理 |
||||
* |
||||
* @param accounts |
||||
* @return |
||||
*/ |
||||
private void operation(JSONArray accounts) throws Exception { |
||||
for (int i = 0; i < accounts.size(); i++) { |
||||
JSONObject account = accounts.getJSONObject(i); |
||||
userSynOperation(account); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 用户同步操作 |
||||
* |
||||
* @param account |
||||
* @throws Exception |
||||
*/ |
||||
private void userSynOperation(JSONObject account) throws Exception { |
||||
String userId = account.getString("uid"); |
||||
UserBean userBean; |
||||
if (UserKit.existUsername(userId)) { |
||||
userBean = UserServiceKit.getInstance().updateUserBean(account); |
||||
if (userBean == null) { |
||||
return; |
||||
} |
||||
UserService.getInstance().editUser(userBean); |
||||
UserService.getInstance().forbidUser(userBean.getId(), userBean.isEnable()); |
||||
UserService.getInstance().updateUserDepartmentPost(UserServiceKit.getInstance().getAdminUserId(), userBean); |
||||
} else { |
||||
userBean = UserServiceKit.getInstance().createUserBean(account); |
||||
try { |
||||
UserService.getInstance().addUser(userBean); |
||||
User user = UserService.getInstance().getUserByUserName(userBean.getUsername()); |
||||
UserService.getInstance().forbidUser(user.getId(), userBean.isEnable()); |
||||
} catch (Exception e) { |
||||
LogKit.error("sso-UserPushController-userSynOperation-Username:{}, RealName:{}, Mobile:{}, Email:{}", |
||||
userBean.getUsername(), userBean.getRealName(), userBean.getMobile(), userBean.getEmail()); |
||||
LogKit.error(e.getMessage(), e); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 解决跨域访问问题 |
||||
* |
||||
* @param res |
||||
*/ |
||||
private void setHeader(HttpServletResponse res) { |
||||
// 跨域设置header
|
||||
res.setHeader("Access-Control-Allow-Origin", "*"); |
||||
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); |
||||
res.setHeader("Access-Control-Max-Age", "3600"); |
||||
res.setHeader("Access-Control-Allow-Headers", "x-requested-with"); |
||||
} |
||||
} |
@ -0,0 +1,158 @@
|
||||
/* |
||||
* Copyright (C), 2018-2021 |
||||
* Project: starter |
||||
* FileName: SsoUserManager |
||||
* Author: Louis |
||||
* Date: 2021/4/21 16:18 |
||||
*/ |
||||
package com.fr.plugin.j7508.sso.user; |
||||
|
||||
import com.auth0.jwt.JWT; |
||||
import com.auth0.jwt.JWTCreator; |
||||
import com.auth0.jwt.algorithms.Algorithm; |
||||
import com.fanruan.api.log.LogKit; |
||||
import com.fanruan.api.net.http.HttpKit; |
||||
import com.fanruan.api.util.StringKit; |
||||
import com.fr.decision.authority.AuthorityContext; |
||||
import com.fr.decision.authority.data.Department; |
||||
import com.fr.decision.base.util.UUIDUtil; |
||||
import com.fr.json.JSONArray; |
||||
import com.fr.json.JSONObject; |
||||
import com.fr.plugin.j7508.sso.config.SsoConfig; |
||||
import com.fr.plugin.j7508.sso.kit.DepartmentServiceKit; |
||||
import com.fr.plugin.j7508.sso.utils.SignatureUtil; |
||||
import com.fr.third.org.apache.http.entity.StringEntity; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import java.util.UUID; |
||||
|
||||
import static com.fr.decision.authority.base.AuthorityConstants.DECISION_DEP_ROOT; |
||||
|
||||
/** |
||||
* <Function Description><br> |
||||
* <SsoUserManager> |
||||
* |
||||
* @author fr.open |
||||
* @since 1.0.0 |
||||
*/ |
||||
public final class SsoUserManager { |
||||
public static final String ORG_LIST_ALL = "/esb/organization/listAll/api"; |
||||
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("sso-SsoUserManager-synSSODepartments-start"); |
||||
// 同步部门和用户信息
|
||||
departmentSynLoop(); |
||||
LogKit.info("sso-SsoUserManager-synSSODepartments-end"); |
||||
} |
||||
|
||||
/** |
||||
* 按部门遍历子部门并同步人员信息 |
||||
* |
||||
* @throws Exception |
||||
*/ |
||||
private void departmentSynLoop() throws IOException { |
||||
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("sso-SsoUserManager-departmentSynOperation-departmentJo:{}", departmentJo.encode()); |
||||
String departmentId = departmentJo.getString("orgCode"); |
||||
if(StringKit.equals(departmentJo.getString("status"),"1")) { |
||||
String parentId = departmentJo.getString("parentCode"); |
||||
if (StringKit.isBlank(parentId)) { parentId = DECISION_DEP_ROOT; } |
||||
String depName = departmentJo.getString("orgName"); |
||||
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("status"), "0")) { |
||||
DepartmentServiceKit.getInstance().deleteDepartment(departmentId); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 通过接口获取部门列表 |
||||
* |
||||
* @return |
||||
* @throws IOException |
||||
*/ |
||||
private JSONArray getDepartmentList() throws IOException { |
||||
Map<String, String> headers = new HashMap<>(); |
||||
headers.put("Content-Type", "application/json;charset=UTF-8"); |
||||
headers.put("requestId", UUIDUtil.generate()); |
||||
headers.put("sourceSystem", "BI"); |
||||
headers.put("serviceName", "S_0004_syncOrgnizeAll_S"); |
||||
JSONObject params = JSONObject.create(); |
||||
params.put("size", "3000"); |
||||
params.put("page", "1"); |
||||
params.put("startTime", StringKit.EMPTY); |
||||
StringEntity stringEntity = new StringEntity(params.encode(), "UTF-8"); |
||||
String response = HttpKit.executeAndParse(com.fanruan.api.net.http.rs.HttpRequest.custom() |
||||
.url(this.config.getEsbUri() + ORG_LIST_ALL).post(stringEntity).headers(headers).build()); |
||||
LogKit.info("sso-SsoUserManager-getDepartmentList-response:{}", response); |
||||
JSONObject responseJo = new JSONObject(response); |
||||
if (StringKit.equals(responseJo.getString("code"), "0")) { |
||||
return responseJo.getJSONObject("data").getJSONArray("list"); |
||||
} |
||||
return JSONArray.create(); |
||||
} |
||||
|
||||
/** |
||||
* 产生JWT token |
||||
* |
||||
* @return |
||||
*/ |
||||
private String getJWTToken() { |
||||
Map<String, String> map = new HashMap<>(); |
||||
map.put("timestamp", System.currentTimeMillis() + ""); |
||||
map.put("noncestr", UUID.randomUUID().toString()); |
||||
map.put("secretKey", this.config.getAppSecret()); |
||||
String sign = SignatureUtil.getSign(map); |
||||
JWTCreator.Builder builder = JWT.create().withAudience(this.config.getAppID()); |
||||
map.remove("secretKey"); |
||||
for (Map.Entry<String, String> entry : map.entrySet()) { |
||||
builder.withClaim(entry.getKey(), entry.getValue()); |
||||
} |
||||
String token = builder.sign(Algorithm.HMAC256(sign)); |
||||
if (StringKit.isNotBlank(token)) { |
||||
return token; |
||||
} |
||||
return StringKit.EMPTY; |
||||
} |
||||
} |
@ -0,0 +1,43 @@
|
||||
package com.fr.plugin.j7508.sso.utils; |
||||
|
||||
import com.fanruan.api.util.StringKit; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Collections; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
public class SignatureUtil { |
||||
public static String getSign(Map<String, String> sortedParams) { |
||||
StringBuilder content = new StringBuilder(); |
||||
List<String> keys = new ArrayList<>(sortedParams.keySet()); |
||||
Collections.sort(keys); |
||||
int index = 0; |
||||
Iterator<String> var4 = keys.iterator(); |
||||
while (var4.hasNext()) { |
||||
String key = var4.next(); |
||||
String value = sortedParams.get(key); |
||||
if (areNotEmpty(new String[] { key, value })) { |
||||
content.append((index == 0) ? "" : "&").append(key).append("=").append(value); |
||||
index++; |
||||
} |
||||
} |
||||
return content.toString(); |
||||
} |
||||
|
||||
public static boolean areNotEmpty(String... values) { |
||||
boolean result = true; |
||||
if (values != null && values.length != 0) { |
||||
String[] var2 = values; |
||||
int var3 = values.length; |
||||
for (int var4 = 0; var4 < var3; var4++) { |
||||
String value = var2[var4]; |
||||
result &= StringKit.isNotEmpty(value); |
||||
} |
||||
} else { |
||||
result = false; |
||||
} |
||||
return result; |
||||
} |
||||
} |
@ -0,0 +1,18 @@
|
||||
Plugin-J7508-Sso=Sso Plugin |
||||
Plugin-J7508-Sso_Group=Sso Plugin |
||||
Plugin-J7508-Sso_Config_FrUri=Fr Uri |
||||
Plugin-J7508-Sso_Config_FrUri_Description=Fr Uri |
||||
Plugin-J7508-Sso_Config_UriBase=Base Uri |
||||
Plugin-J7508-Sso_Config_UriBase_Description=Base Uri |
||||
Plugin-J7508-Sso_Config_EsbUri=Esb Uri |
||||
Plugin-J7508-Sso_Config_EsbUri_Description=Esb Uri |
||||
Plugin-J7508-Sso_Config_ClientId=Client Id |
||||
Plugin-J7508-Sso_Config_ClientId_Description=Client Id |
||||
Plugin-J7508-Sso_Config_ClientSecret=Client Secret |
||||
Plugin-J7508-Sso_Config_ClientSecret_Description=Client Secret |
||||
Plugin-J7508-Sso_Config_CronCondition=Cron Condition |
||||
Plugin-J7508-Sso_Config_CronCondition_Description=Cron Condition |
||||
Plugin-J7508-Sso_Config_AppID=App ID |
||||
Plugin-J7508-Sso_Config_AppID_Description=App ID |
||||
Plugin-J7508-Sso_Config_AppSecret=App Secret |
||||
Plugin-J7508-Sso_Config_AppSecret_Description=App Secret |
@ -0,0 +1,18 @@
|
||||
Plugin-J7508-Sso=\u5355\u70B9\u767B\u9646\u63D2\u4EF6 |
||||
Plugin-J7508-Sso_Group=\u5355\u70B9\u767B\u9646\u63D2\u4EF6 |
||||
Plugin-J7508-Sso_Config_FrUri=\u51B3\u7B56\u7CFB\u7EDFURL |
||||
Plugin-J7508-Sso_Config_FrUri_Description=\u51B3\u7B56\u7CFB\u7EDFURL |
||||
Plugin-J7508-Sso_Config_UriBase=\u767B\u9646\u8BA4\u8BC1\u63A5\u53E3 |
||||
Plugin-J7508-Sso_Config_UriBase_Description=\u767B\u9646\u8BA4\u8BC1\u63A5\u53E3 |
||||
Plugin-J7508-Sso_Config_EsbUri=\u7EC4\u7EC7\u4FE1\u606F\u63A5\u53E3 |
||||
Plugin-J7508-Sso_Config_EsbUri_Description=\u7EC4\u7EC7\u4FE1\u606F\u63A5\u53E3 |
||||
Plugin-J7508-Sso_Config_ClientId=\u5E94\u7528\u6CE8\u518CID |
||||
Plugin-J7508-Sso_Config_ClientId_Description=\u5E94\u7528\u6CE8\u518CID |
||||
Plugin-J7508-Sso_Config_ClientSecret=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801 |
||||
Plugin-J7508-Sso_Config_ClientSecret_Description=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801 |
||||
Plugin-J7508-Sso_Config_CronCondition=Cron\u8868\u8FBE\u5F0F |
||||
Plugin-J7508-Sso_Config_CronCondition_Description=Cron\u8868\u8FBE\u5F0F |
||||
Plugin-J7508-Sso_Config_AppID=IAM\u7533\u8BF7\u88AB\u63A8App ID |
||||
Plugin-J7508-Sso_Config_AppID_Description=idm\u5E94\u7528\u914D\u7F6E\u7533\u8BF7\u7684\u88AB\u63A8App ID |
||||
Plugin-J7508-Sso_Config_AppSecret=IAM\u7533\u8BF7\u88AB\u63A8App Secret |
||||
Plugin-J7508-Sso_Config_AppSecret_Description=idm\u5E94\u7528\u914D\u7F6E\u7533\u8BF7\u7684\u88AB\u63A8App Secret |
Loading…
Reference in new issue