LAPTOP-SB56SG4Q\86185
3 years ago
13 changed files with 432 additions and 1 deletions
Binary file not shown.
Binary file not shown.
@ -1,3 +1,6 @@ |
|||||||
# open-JSD-9446 |
# open-JSD-9446 |
||||||
|
|
||||||
OAuth2 单点 |
JSD-9446 OAuth2 单点\ |
||||||
|
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||||
|
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||||
|
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
Binary file not shown.
@ -0,0 +1,25 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<plugin> |
||||||
|
<id>com.fr.plugin.idnf.sso</id> |
||||||
|
<name><![CDATA[单点登陆&用户权限]]></name> |
||||||
|
<active>yes</active> |
||||||
|
<version>1.0</version> |
||||||
|
<env-version>10.0</env-version> |
||||||
|
<jartime>2018-07-31</jartime> |
||||||
|
<vendor>fr.open</vendor> |
||||||
|
<description><![CDATA[单点登陆&用户权限]]></description> |
||||||
|
<change-notes><![CDATA[单点登陆&用户权限]]></change-notes> |
||||||
|
<main-package>com.fr.plugin.idnf</main-package> |
||||||
|
<prefer-packages> |
||||||
|
<prefer-package>com.fanruan.api</prefer-package> |
||||||
|
</prefer-packages> |
||||||
|
<lifecycle-monitor class="com.fr.plugin.idnf.PluginMonitor"/> |
||||||
|
<extra-core> |
||||||
|
<LocaleFinder class="com.fr.plugin.idnf.LocaleFinder"/> |
||||||
|
</extra-core> |
||||||
|
<extra-decision> |
||||||
|
<GlobalRequestFilterProvider class="com.fr.plugin.idnf.request.OAuthLogin"/> |
||||||
|
<ControllerRegisterProvider class="com.fr.plugin.idnf.service.AuthControllerBridge"/> |
||||||
|
</extra-decision> |
||||||
|
<function-recorder class="com.fr.plugin.idnf.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.idnf; |
||||||
|
|
||||||
|
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.idnf.config.IdnfConfig.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-idnf", source = Original.PLUGIN) |
||||||
|
public String find() { |
||||||
|
return "com/fr/plugin/idnf/locale/lang"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int currentAPILevel() { |
||||||
|
return CURRENT_LEVEL; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C), 2018-2021 |
||||||
|
* Project: starter |
||||||
|
* FileName: PluginMonitor |
||||||
|
* Author: Louis |
||||||
|
* Date: 2021/3/30 15:10 |
||||||
|
*/ |
||||||
|
package com.fr.plugin.idnf; |
||||||
|
|
||||||
|
import com.fr.plugin.context.PluginContext; |
||||||
|
import com.fr.plugin.idnf.config.IdnfConfig; |
||||||
|
import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; |
||||||
|
|
||||||
|
/** |
||||||
|
* <Function Description><br> |
||||||
|
* <PluginMonitor> |
||||||
|
* |
||||||
|
* @author fr.open |
||||||
|
* @since 1.0.0 |
||||||
|
*/ |
||||||
|
public class PluginMonitor extends AbstractPluginLifecycleMonitor { |
||||||
|
public PluginMonitor() { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void afterRun(PluginContext pluginContext) { |
||||||
|
IdnfConfig.getInstance(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void beforeStop(PluginContext pluginContext) { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C), 2018-2021 |
||||||
|
* Project: starter |
||||||
|
* FileName: IdnfConfig |
||||||
|
* Author: Louis |
||||||
|
* Date: 2021/3/30 9:38 |
||||||
|
*/ |
||||||
|
package com.fr.plugin.idnf.config; |
||||||
|
|
||||||
|
import com.fr.config.*; |
||||||
|
import com.fr.config.holder.Conf; |
||||||
|
import com.fr.config.holder.factory.Holders; |
||||||
|
|
||||||
|
/** |
||||||
|
* <Function Description><br> |
||||||
|
* <SsoConfig> |
||||||
|
* |
||||||
|
* @author fr.open |
||||||
|
* @since 1.0.0 |
||||||
|
*/ |
||||||
|
@Visualization(category = "Plugin-idnf_Group") |
||||||
|
public class IdnfConfig extends DefaultConfiguration { |
||||||
|
public static final String PLUGIN_ID = "com.fr.plugin.idnf.sso"; |
||||||
|
|
||||||
|
private static volatile IdnfConfig config = null; |
||||||
|
@Identifier(value = "keyCode", name = "Plugin-idnf_Config_KeyCode", description = "Plugin-idnf_Config_KeyCode_Description", status = Status.SHOW) |
||||||
|
private final Conf<String> keyCode = Holders.simple("username"); |
||||||
|
|
||||||
|
public static IdnfConfig getInstance() { |
||||||
|
if (config == null) { |
||||||
|
config = ConfigContext.getConfigInstance(IdnfConfig.class); |
||||||
|
} |
||||||
|
return config; |
||||||
|
} |
||||||
|
|
||||||
|
public String getKeyCode() { |
||||||
|
return keyCode.get(); |
||||||
|
} |
||||||
|
|
||||||
|
public void setKeyCode(String keyCode) { |
||||||
|
this.keyCode.set(keyCode); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,118 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C), 2018-2021 |
||||||
|
* Project: starter |
||||||
|
* FileName: OAuthLogin |
||||||
|
* Author: Louis |
||||||
|
* Date: 2021/3/30 22:09 |
||||||
|
*/ |
||||||
|
package com.fr.plugin.idnf.request; |
||||||
|
|
||||||
|
import com.fanruan.api.decision.login.LoginKit; |
||||||
|
import com.fanruan.api.decision.user.UserKit; |
||||||
|
import com.fanruan.api.i18n.I18nKit; |
||||||
|
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.plugin.context.PluginContexts; |
||||||
|
import com.fr.plugin.idnf.config.IdnfConfig; |
||||||
|
import com.fr.stable.fun.Authorize; |
||||||
|
|
||||||
|
import javax.servlet.FilterChain; |
||||||
|
import javax.servlet.FilterConfig; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
|
||||||
|
import static com.fr.plugin.idnf.config.IdnfConfig.PLUGIN_ID; |
||||||
|
import static com.fr.plugin.idnf.service.AuthController.AUTH_PATH; |
||||||
|
|
||||||
|
/** |
||||||
|
* <Function Description><br> |
||||||
|
* <OAuthLogin> |
||||||
|
* |
||||||
|
* @author fr.open |
||||||
|
* @since 1.0.0 |
||||||
|
*/ |
||||||
|
@Authorize(callSignKey = PLUGIN_ID) |
||||||
|
public class OAuthLogin extends AbstractGlobalRequestFilterProvider { |
||||||
|
private IdnfConfig config; |
||||||
|
|
||||||
|
/** |
||||||
|
* 过滤器名称 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String filterName() { |
||||||
|
return "idnfFilter"; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 过滤规则 |
||||||
|
* |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public String[] urlPatterns() { |
||||||
|
return new String[]{"/decision", "/decision/view/form", "/decision/view/report", "/decision/v10/entry/access/*", "/decision/v5/design/report/*", AUTH_PATH}; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 过滤器初始化 |
||||||
|
* |
||||||
|
* @param filterConfig |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void init(FilterConfig filterConfig) { |
||||||
|
this.config = IdnfConfig.getInstance(); |
||||||
|
super.init(filterConfig); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 过滤器处理 |
||||||
|
* |
||||||
|
* @param request |
||||||
|
* @param response |
||||||
|
* @param filterChain |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) { |
||||||
|
try { |
||||||
|
operation(request, response); |
||||||
|
filterChain.doFilter(request, response); |
||||||
|
} catch (Exception e) { |
||||||
|
LogKit.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 用户验证登陆操作 |
||||||
|
* |
||||||
|
* @param req |
||||||
|
* @param res |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
private void operation(HttpServletRequest req, HttpServletResponse res) throws Exception { |
||||||
|
// 已登录
|
||||||
|
if (LoginService.getInstance().isLogged(req)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String code = NetworkKit.getHTTPRequestParameter(req, this.config.getKeyCode()); |
||||||
|
LogKit.info("idnf-OAuthLogin-operation-code:{}", code); |
||||||
|
if (StringKit.isBlank(code)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
String username = code; |
||||||
|
if (StringKit.isEmpty(username) || !UserKit.existUsername(username)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!PluginContexts.currentContext().isAvailable()) { |
||||||
|
LogKit.error(I18nKit.getLocText("Plugin-idnf_Licence_Expired")); |
||||||
|
return; |
||||||
|
} |
||||||
|
String tokenFR = LoginKit.login(req, res, username); |
||||||
|
req.setAttribute(DecisionServiceConstants.FINE_AUTH_TOKEN_NAME, tokenFR); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,123 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C), 2018-2022 |
||||||
|
* Project: starter |
||||||
|
* FileName: AuthController |
||||||
|
* Author: Louis |
||||||
|
* Date: 2022/1/19 23:47 |
||||||
|
*/ |
||||||
|
package com.fr.plugin.idnf.service; |
||||||
|
|
||||||
|
import com.fanruan.api.decision.login.LoginKit; |
||||||
|
import com.fanruan.api.log.LogKit; |
||||||
|
import com.fanruan.api.util.StringKit; |
||||||
|
import com.fr.decision.authority.AuthorityContext; |
||||||
|
import com.fr.decision.authority.base.constant.type.authority.ViewAuthorityType; |
||||||
|
import com.fr.decision.authority.data.Authority; |
||||||
|
import com.fr.decision.authority.data.User; |
||||||
|
import com.fr.decision.authority.data.extra.ExtraPropertyKey; |
||||||
|
import com.fr.decision.finebi.data.user.type.BIDataAnalysisKey; |
||||||
|
import com.fr.decision.finebi.data.user.type.BIDataProcessKey; |
||||||
|
import com.fr.decision.finebi.data.user.type.BIDesignKey; |
||||||
|
import com.fr.decision.finebi.data.user.type.BIViewKey; |
||||||
|
import com.fr.decision.webservice.Response; |
||||||
|
import com.fr.decision.webservice.annotation.LoginStatusChecker; |
||||||
|
import com.fr.decision.webservice.v10.user.UserService; |
||||||
|
import com.fr.general.ComparatorUtils; |
||||||
|
import com.fr.json.JSONObject; |
||||||
|
import com.fr.stable.query.QueryFactory; |
||||||
|
import com.fr.third.springframework.stereotype.Controller; |
||||||
|
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.HttpServletRequest; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
/** |
||||||
|
* <Function Description><br> |
||||||
|
* <AuthController> |
||||||
|
* |
||||||
|
* @author fr.open |
||||||
|
* @since 1.0.0 |
||||||
|
*/ |
||||||
|
@Controller |
||||||
|
@RequestMapping("jsd3645") |
||||||
|
public class AuthController { |
||||||
|
public static final String DECISION_MANAGEMENT_ROOT = "decision-management-root"; |
||||||
|
public static final String DECISION_DIRECTORY_ROOT = "decision-directory-root"; |
||||||
|
public static final String BI_USE_ROOT = "bi-use-root"; |
||||||
|
public static final String AUTH_PATH = "/decision/jsd3645/auth"; |
||||||
|
|
||||||
|
@RequestMapping(value = "auth", method = RequestMethod.GET) |
||||||
|
@ResponseBody |
||||||
|
@LoginStatusChecker(required = false) |
||||||
|
public Response authGet(HttpServletRequest req, 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"); |
||||||
|
String username = LoginKit.getCurrentUserNameFromRequest(req); |
||||||
|
if (StringKit.isBlank(username)) { |
||||||
|
username = LoginKit.getCurrentUserNameFromRequestCookie(req); |
||||||
|
} |
||||||
|
try { |
||||||
|
User user = UserService.getInstance().getUserByUserName(username); |
||||||
|
JSONObject data = new JSONObject(); |
||||||
|
data.put("decisionManagementRoot", isDecisionManagementRoot(user.getId())); |
||||||
|
data.put("decisionDirectoryRoot", isDecisionDirectoryRoot(user)); |
||||||
|
data.put("biUseRoot", isBiUse(user)); |
||||||
|
return (new Response()).status(200).errorCode("0").data(data); |
||||||
|
} catch (Exception e) { |
||||||
|
LogKit.error(e.getMessage(), e); |
||||||
|
} |
||||||
|
return (new Response()).status(200).errorCode("1"); |
||||||
|
} |
||||||
|
|
||||||
|
private Boolean isDecisionManagementRoot(String userId) throws Exception { |
||||||
|
List<Authority> authorityList = AuthorityContext.getInstance().getAuthorityController().findByUser(userId, |
||||||
|
ViewAuthorityType.TYPE, |
||||||
|
QueryFactory.create()); |
||||||
|
for (Authority authority : authorityList) { |
||||||
|
if (ComparatorUtils.equals(authority.getParentId(), DECISION_MANAGEMENT_ROOT)) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param user |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private Boolean isDecisionDirectoryRoot(User user) { |
||||||
|
Map<ExtraPropertyKey, Object> extraPropertyKeyObjectMap = user.getExtraPropertyMap(); |
||||||
|
if (extraPropertyKeyObjectMap.containsKey(BIDataAnalysisKey.KEY) |
||||||
|
|| extraPropertyKeyObjectMap.containsKey(BIDataProcessKey.KEY) |
||||||
|
|| extraPropertyKeyObjectMap.containsKey(BIDesignKey.KEY) |
||||||
|
|| extraPropertyKeyObjectMap.containsKey(BIViewKey.KEY) |
||||||
|
) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* BI权限 |
||||||
|
* |
||||||
|
* @param user |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
private Boolean isBiUse(User user) { |
||||||
|
Map<ExtraPropertyKey, Object> extraPropertyKeyObjectMap = user.getExtraPropertyMap(); |
||||||
|
if (extraPropertyKeyObjectMap.containsKey(BIDataAnalysisKey.KEY) |
||||||
|
|| extraPropertyKeyObjectMap.containsKey(BIDataProcessKey.KEY) |
||||||
|
|| extraPropertyKeyObjectMap.containsKey(BIDesignKey.KEY) |
||||||
|
) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C), 2018-2022 |
||||||
|
* Project: starter |
||||||
|
* FileName: AuthControllerBridge |
||||||
|
* Author: Louis |
||||||
|
* Date: 2022/1/19 23:45 |
||||||
|
*/ |
||||||
|
package com.fr.plugin.idnf.service; |
||||||
|
|
||||||
|
import com.fr.decision.fun.impl.AbstractControllerRegisterProvider; |
||||||
|
|
||||||
|
/** |
||||||
|
* <Function Description><br> |
||||||
|
* <AuthControllerBridge> |
||||||
|
* |
||||||
|
* @author fr.open |
||||||
|
* @since 1.0.0 |
||||||
|
*/ |
||||||
|
public class AuthControllerBridge extends AbstractControllerRegisterProvider { |
||||||
|
|
||||||
|
@Override |
||||||
|
public Class[] getControllers() { |
||||||
|
return new Class[]{ |
||||||
|
AuthController.class |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
Plugin-idnf=Sso Plugin |
||||||
|
Plugin-idnf_Group=Sso Plugin |
||||||
|
Plugin-idnf_Config_KeyCode=Key Code |
||||||
|
Plugin-idnf_Config_KeyCode_Description=Key Code |
||||||
|
Plugin-idnf_Licence_Expired=Sso Plugin Licence Expired |
||||||
|
Plugin-idnf_Config_ClientId=Client Id |
||||||
|
Plugin-idnf_Config_ClientId_Description=Client Id |
||||||
|
Plugin-idnf_Config_ClientSecret=Client Secret |
||||||
|
Plugin-idnf_Config_ClientSecret_Description=Client Secret |
||||||
|
Plugin-idnf_Config_FrUri=FR Uri |
||||||
|
Plugin-idnf_Config_FrUri_Description=FR Uri |
@ -0,0 +1,11 @@ |
|||||||
|
Plugin-idnf=\u5355\u70B9\u767B\u9646\u63D2\u4EF6 |
||||||
|
Plugin-idnf_Group=\u5355\u70B9\u767B\u9646\u63D2\u4EF6 |
||||||
|
Plugin-idnf_Config_KeyCode=Key Code |
||||||
|
Plugin-idnf_Config_KeyCode_Description=Key Code |
||||||
|
Plugin-idnf_Licence_Expired=\u5355\u70B9\u767B\u9646\u63D2\u4EF6\u8BB8\u53EF\u8FC7\u671F |
||||||
|
Plugin-idnf_Config_ClientId=\u5E94\u7528\u6CE8\u518CID |
||||||
|
Plugin-idnf_Config_ClientId_Description=\u5E94\u7528\u6CE8\u518CID |
||||||
|
Plugin-idnf_Config_ClientSecret=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801 |
||||||
|
Plugin-idnf_Config_ClientSecret_Description=\u5E94\u7528\u6CE8\u518C\u5BC6\u7801 |
||||||
|
Plugin-idnf_Config_FrUri=\u5E06\u8F6F\u7CFB\u7EDFurl |
||||||
|
Plugin-idnf_Config_FrUri_Description=\u5E06\u8F6F\u7CFB\u7EDFurl |
Loading…
Reference in new issue