commit 1d486f4135760cc8e12530007e4b95eedada36a9 Author: pioneer Date: Thu Jul 14 11:57:04 2022 +0800 open diff --git a/README.md b/README.md new file mode 100644 index 0000000..ad13f0d --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# open-JSD-9724 + +JSD-9724 单点集成\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 \ No newline at end of file diff --git a/doc/JSD-9724-需求确认书V1.1.docx b/doc/JSD-9724-需求确认书V1.1.docx new file mode 100644 index 0000000..a6aa9a7 Binary files /dev/null and b/doc/JSD-9724-需求确认书V1.1.docx differ diff --git a/doc/单点登录插件使用文档.docx b/doc/单点登录插件使用文档.docx new file mode 100644 index 0000000..190760f Binary files /dev/null and b/doc/单点登录插件使用文档.docx differ diff --git a/lib/finekit-10.0-20200828.jar b/lib/finekit-10.0-20200828.jar new file mode 100644 index 0000000..47de3ae Binary files /dev/null and b/lib/finekit-10.0-20200828.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..eb27061 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,22 @@ + + + com.fr.plugin.foauth.login + + yes + 1.0.2 + 10.0 + 2020-07-31 + fr.open + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/FJ1Filter.java b/src/main/java/com/fr/plugin/FJ1Filter.java new file mode 100644 index 0000000..553b4a9 --- /dev/null +++ b/src/main/java/com/fr/plugin/FJ1Filter.java @@ -0,0 +1,127 @@ +package com.fr.plugin; + +import com.fanruan.api.security.SecurityKit; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.stable.StringUtils; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLEncoder; + + +@FunctionRecorder(localeKey = "fr2") +public class FJ1Filter extends AbstractGlobalRequestFilterProvider { + @Override + public String filterName() { + return "fj" ; + } + + @Override + public String[] urlPatterns() { + return new String[]{ + "/*" + }; + } + + @Override + public void init(FilterConfig filterConfig) { + FLConfig xtlConfig = FLConfig.getInstance(); + FineLoggerFactory.getLogger().info("初始化"); + super.init(filterConfig); + } + + @Override + public void doFilter(HttpServletRequest request, HttpServletResponse httpServletResponse, FilterChain filterChain) { + try { + if(needFilter(request) && !isLogin(request)) { + sendRedirect(httpServletResponse, goAuth()); + return; + } + filterChain.doFilter(request, httpServletResponse); + } catch (IOException | ServletException e) { + printException2FrLog(e); + } catch (Exception e) { + e.printStackTrace(); + } + } + private String goAuth() { + FLConfig xtlConfig = FLConfig.getInstance(); + String valAddr = xtlConfig.getValAddr(); + String service = xtlConfig.getService(); + String appid = xtlConfig.getAppid(); + String frurl = null; + try { + frurl = URLEncoder.encode(xtlConfig.getFrUrl() + "/url/oauth2/login","UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + String url = String.format("%s/am/oauth2/authorize?service=%s&" + + "response_type=code&client_id=%s&" + + "scope=uid+cn+userIdCode&redirect_uri=%s&decision=Allow", valAddr, service,appid, frurl); + return url; + } + private boolean needFilter(HttpServletRequest request) { + String requestURI = request.getRequestURI(); + String isAdmin = request.getParameter("isAdmin"); + if (StringUtils.equals(isAdmin, "1")) { + return false; + } + if (StringUtils.isNotBlank(requestURI) && request.getMethod().equals("GET")) { + if (requestURI.endsWith("decision")) { + return true; + } + if (requestURI.endsWith("/view/form") || requestURI.endsWith("/view/report")) { + if (StringUtils.isNotBlank(request.getParameter("viewlet"))) { + return true; + } + } + if (requestURI.contains("/v10/entry/access/") && request.getMethod().equals("GET")) { + return true; + } + if (requestURI.contains("/v5/design/report") && (requestURI.endsWith("/edit") || requestURI.endsWith("/view"))) { + return true; + } + } + return false; + } + + public static void printException2FrLog(Throwable e) { + StringWriter writer = new StringWriter(); + e.printStackTrace(new PrintWriter(writer)); + String s = writer.toString(); + FineLoggerFactory.getLogger().error("错误:{}", s); + } + + private void sendRedirect(HttpServletResponse res, String url) { + res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); + res.setHeader("Location", url); + } + + + private void login(HttpServletRequest req, HttpServletResponse res, String username) { + String token = null; + try { + token = LoginService.getInstance().login(req, res, username); + req.setAttribute("fine_auth_token", token); + FineLoggerFactory.getLogger().error("login success"); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineLoggerFactory.getLogger().error("login failed"); + } + } + + private boolean isLogin(HttpServletRequest req) { + return LoginService.getInstance().isLogged(req); + } +} diff --git a/src/main/java/com/fr/plugin/FLConfig.java b/src/main/java/com/fr/plugin/FLConfig.java new file mode 100644 index 0000000..e9881c8 --- /dev/null +++ b/src/main/java/com/fr/plugin/FLConfig.java @@ -0,0 +1,83 @@ +package com.fr.plugin; + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +@Visualization(category = "单点配置") +public class FLConfig extends DefaultConfiguration { + + private static volatile FLConfig config = null; + + public static FLConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(FLConfig.class); + } + return config; + } + + @Identifier(value = "valAddr", name = "接口地址", description = "接口地址", status = Status.SHOW) + private Conf valAddr = Holders.simple(""); + @Identifier(value = "service", name = "认证链名称,默认为:initService", description = "接口地址", status = Status.SHOW) + private Conf service = Holders.simple("initService"); + @Identifier(value = "appid", name = "应用的ClientId", description = "应用被推颁发的AppID", status = Status.SHOW) + private Conf appid = Holders.simple(""); + @Identifier(value = "loginClientSecret", name = "Client_secret", description = "Secret", status = Status.SHOW) + private Conf loginClientSecret = Holders.simple(""); + @Identifier(value = "frUrl", name = "当前fr系统地址", description = "", status = Status.SHOW) + private Conf frUrl = Holders.simple("http://localhost:8075/webroot/decision"); + + public String getService() { + return service.get(); + } + + public void setService(String service) { + this.service.set(service); + } + + public String getFrUrl() { + return frUrl.get(); + } + + public void setFrUrl(String frUrl) { + this.frUrl.set(frUrl); + } + + public String getLoginClientSecret() { + return loginClientSecret.get(); + } + + public void setLoginClientSecret(String loginClientSecret) { + this.loginClientSecret.set(loginClientSecret); + } + + public String getAppid() { + return appid.get(); + } + + public void setAppid(String appid) { + this.appid.set(appid); + } + + public String getValAddr() { + return valAddr.get(); + } + + public void setValAddr(String valAddr) { + this.valAddr.set(valAddr); + } + + + + @Override + public Object clone() throws CloneNotSupportedException { + FLConfig cloned = (FLConfig) super.clone(); + cloned.valAddr = (Conf) valAddr.clone(); + cloned.service = (Conf) service.clone(); + cloned.appid = (Conf) appid.clone(); + cloned.loginClientSecret = (Conf) loginClientSecret.clone(); + cloned.frUrl = (Conf) frUrl.clone(); + return cloned; + } + +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/FLHttpHander.java b/src/main/java/com/fr/plugin/FLHttpHander.java new file mode 100644 index 0000000..1114a61 --- /dev/null +++ b/src/main/java/com/fr/plugin/FLHttpHander.java @@ -0,0 +1,15 @@ +package com.fr.plugin; + +import com.fr.decision.fun.HttpHandler; +import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; +import com.fr.plugin.handler.FLLoginCallBackHander; + +public class FLHttpHander extends AbstractHttpHandlerProvider { + + private HttpHandler[] actions = new HttpHandler[]{new FLLoginCallBackHander() }; + + @Override + public HttpHandler[] registerHandlers() { + return actions; + } +} diff --git a/src/main/java/com/fr/plugin/FLLifeCycleMonitor.java b/src/main/java/com/fr/plugin/FLLifeCycleMonitor.java new file mode 100644 index 0000000..02171e4 --- /dev/null +++ b/src/main/java/com/fr/plugin/FLLifeCycleMonitor.java @@ -0,0 +1,16 @@ +package com.fr.plugin; + +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + +public class FLLifeCycleMonitor extends AbstractPluginLifecycleMonitor { + @Override + public void afterRun(PluginContext pluginContext) { + FLConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + + } +} diff --git a/src/main/java/com/fr/plugin/FLPassportProvider.java b/src/main/java/com/fr/plugin/FLPassportProvider.java new file mode 100644 index 0000000..f4a5b9c --- /dev/null +++ b/src/main/java/com/fr/plugin/FLPassportProvider.java @@ -0,0 +1,24 @@ +package com.fr.plugin; + +import com.fr.decision.authorize.Passport; +import com.fr.decision.fun.impl.AbstractPassportProvider; +import com.fr.decision.webservice.bean.authentication.PassportBean; + +public class FLPassportProvider extends AbstractPassportProvider { + public static final String PASSPORT_TYPE = "oauth2"; + + @Override + public String passportType() { + return PASSPORT_TYPE; + } + + @Override + public Class classForPassportBean() { + return Oauth2Bean.class; + } + + @Override + public Class classForPassportConfig() { + return Oauth2Passport.class; + } +} diff --git a/src/main/java/com/fr/plugin/FLURLAliasBridge.java b/src/main/java/com/fr/plugin/FLURLAliasBridge.java new file mode 100644 index 0000000..e824b15 --- /dev/null +++ b/src/main/java/com/fr/plugin/FLURLAliasBridge.java @@ -0,0 +1,22 @@ +package com.fr.plugin; + +import com.fr.decision.fun.impl.AbstractURLAliasProvider; +import com.fr.decision.webservice.url.alias.URLAlias; +import com.fr.decision.webservice.url.alias.URLAliasFactory; +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; + + +@FunctionRecorder +public class FLURLAliasBridge extends AbstractURLAliasProvider +{ + + @Override + @ExecuteFunctionRecord + public URLAlias[] registerAlias() { + //像这样配置之后再访问/api就可以通过http(s)://ip:port/webroot/decision/url/api。 进行访问 + return new URLAlias[]{ + URLAliasFactory.createPluginAlias("/oauth2/login", "/login", true), + }; + } +} diff --git a/src/main/java/com/fr/plugin/LogindJSHandler.java b/src/main/java/com/fr/plugin/LogindJSHandler.java new file mode 100644 index 0000000..3ec6722 --- /dev/null +++ b/src/main/java/com/fr/plugin/LogindJSHandler.java @@ -0,0 +1,34 @@ +package com.fr.plugin; + +import com.fr.decision.fun.impl.AbstractWebResourceProvider; +import com.fr.decision.web.MainComponent; +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.stable.fun.Authorize; +import com.fr.web.struct.Atom; +@Authorize(callSignKey = "com.fr.plugin.custom.logo" ) +@FunctionRecorder +public class LogindJSHandler extends AbstractWebResourceProvider { + + /** + * 需要附加到的主组件 + * + * @return 主组件 + */ + + @Override + @ExecuteFunctionRecord + public Atom attach() { + return MainComponent.KEY; + } + + /** + * 客户端所需的组件 + * + * @return 组件 + */ + @Override + public Atom client() { + return LoginedLogoComponent.KEY; + } +} diff --git a/src/main/java/com/fr/plugin/LoginedLogoComponent.java b/src/main/java/com/fr/plugin/LoginedLogoComponent.java new file mode 100644 index 0000000..55c357f --- /dev/null +++ b/src/main/java/com/fr/plugin/LoginedLogoComponent.java @@ -0,0 +1,54 @@ +package com.fr.plugin; + +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.web.struct.Component; +import com.fr.web.struct.Filter; +import com.fr.web.struct.browser.RequestClient; +import com.fr.web.struct.category.ScriptPath; +import com.fr.web.struct.category.StylePath; +@FunctionRecorder() +public class LoginedLogoComponent extends Component { + public static final LoginedLogoComponent KEY = new LoginedLogoComponent(); + /** + * 返回需要引入的JS脚本路径 + * @param client 请求客户端描述 + * @return JS脚本路径 + */ + @ExecuteFunctionRecord + public ScriptPath script( RequestClient client ) { + PluginLicense pluginLicense = PluginLicenseManager.getInstance().getPluginLicenseByID("com.fr.plugin.custom.logo"); + if (pluginLicense.isAvailable()) { + // 做认证通过的事情 + return ScriptPath.build("com/fr/plugin/web/logined.js"); + } else { + // 做认证未通过的事情 + return ScriptPath.build("com/fr/plugin/web/webnuy.js"); + } + + } + + /** + * 返回需要引入的CSS样式路径 + * @param client 请求客户端描述 + * @return CSS样式路径 + */ + public StylePath style( RequestClient client ) { + //如果不需要就直接返回 StylePath.EMPTY; + return StylePath.EMPTY; + } + + /** + * 通过给定的资源过滤器控制是否加载这个资源 + * @return 资源过滤器 + */ + public Filter filter() { + return new Filter(){ + @Override + public boolean accept() { + //任何情况下我们都在平台组件加载时加载我们的组件 + return true; + } + }; + } +} diff --git a/src/main/java/com/fr/plugin/Oauth2Bean.java b/src/main/java/com/fr/plugin/Oauth2Bean.java new file mode 100644 index 0000000..f4f40a7 --- /dev/null +++ b/src/main/java/com/fr/plugin/Oauth2Bean.java @@ -0,0 +1,25 @@ +package com.fr.plugin; + +import com.fanruan.api.decision.auth.bean.BasePassportBean; +import com.fr.decision.authorize.Passport; +import com.fr.third.fasterxml.jackson.annotation.JsonSubTypes; + +@JsonSubTypes.Type(value = Oauth2Bean.class, name = "LdapAuthenticBean") +public class Oauth2Bean extends BasePassportBean{ + + @Override + public String markType() { + return FLPassportProvider.PASSPORT_TYPE; + } + + @Override + public BasePassportBean createPassportBean(Oauth2Passport oauth2Passport) { + return this; + } + + @Override + public Passport createPassport() { + Oauth2Passport oauth2Passport = new Oauth2Passport(); + return oauth2Passport; + } +} diff --git a/src/main/java/com/fr/plugin/Oauth2Passport.java b/src/main/java/com/fr/plugin/Oauth2Passport.java new file mode 100644 index 0000000..c9766ec --- /dev/null +++ b/src/main/java/com/fr/plugin/Oauth2Passport.java @@ -0,0 +1,64 @@ +package com.fr.plugin; + +import com.fanruan.api.conf.HolderKit; +import com.fanruan.api.decision.auth.BasePassport; +import com.fanruan.api.net.http.HttpKit; +import com.fanruan.api.util.AssistKit; +import com.fanruan.api.util.StringKit; +import com.fr.config.Identifier; +import com.fr.config.holder.Conf; +import com.fr.stable.StringUtils; + +import java.io.IOException; + +public class Oauth2Passport extends BasePassport { + @Override + public String markType() { + return FLPassportProvider.PASSPORT_TYPE; + } + + @Identifier("emptytoken") + private Conf emptytoken = HolderKit.simple(StringKit.EMPTY); + + @Override + public int hashCode() { + return AssistKit.hashCode(emptytoken.get()); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public String getEmptytoken() { + return emptytoken.get(); + } + + public void setEmptytoken(String emptytoken) { + this.emptytoken.set(emptytoken); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Oauth2Passport)) { + return false; + } + Oauth2Passport target = (Oauth2Passport) obj; + return AssistKit.equals(target.getEmptytoken(), this.getEmptytoken()); + } + + @Override + public boolean checkTicket(String username, String inputPassword, String savedPassword, String hashPassword) { + //调用接口验证账号密码 + FLConfig flConfig = FLConfig.getInstance(); + String url = String.format("%s/am/identity/authenticate?username=%s&password=%s&uri=service=initService", flConfig.getValAddr(), username, inputPassword); + try { + String resp = HttpKit.get(url); + return StringUtils.contains(resp,"token.id="); + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + +} diff --git a/src/main/java/com/fr/plugin/handler/FLLoginCallBackHander.java b/src/main/java/com/fr/plugin/handler/FLLoginCallBackHander.java new file mode 100644 index 0000000..aa5af8e --- /dev/null +++ b/src/main/java/com/fr/plugin/handler/FLLoginCallBackHander.java @@ -0,0 +1,161 @@ +package com.fr.plugin.handler; + +import com.fanruan.api.net.http.HttpKit; +import com.fr.data.NetworkHelper; +import com.fr.decision.authority.data.User; +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.decision.mobile.terminal.TerminalHandler; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.decision.webservice.v10.login.TokenResource; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.general.ComparatorUtils; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.FLConfig; +import com.fr.security.JwtUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.web.Device; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class FLLoginCallBackHander extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return null; + } + + @Override + public String getPath() { + return "/login"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception { + String token = req.getParameter("code"); + if (StringUtils.isNotBlank(token)) { + String accessToken = getAccessToken(token); + if (StringUtils.isEmpty(accessToken)) { + WebUtils.printAsString(res, " 通过" + token + "获取accessToken失败返回内容无效"); + return; + } + String userId = getUserId(accessToken); + if (StringUtils.isEmpty(userId)) { + WebUtils.printAsString(res, " 通过" + accessToken + "获取用户失败返回内容无效"); + return; + } + UserService userService = UserService.getInstance(); + User user = userService.getUserByUserName(userId); + if (user != null) { + login(req, res, userId); + FLConfig xtlConfig = FLConfig.getInstance(); + String frUrl = xtlConfig.getFrUrl(); + sendRedirect(res, frUrl); + return; + } else { + WebUtils.printAsString(res, "用户" + userId + "在帆软系统中不存在"); + return; + } + } else { + sendRedirect(res, goAuth()); + } + } + + private String getUserId(String accessToken) throws IOException { + FLConfig xtlConfig = FLConfig.getInstance(); + String valAddr = xtlConfig.getValAddr(); + String url = String.format("%s/am/oauth2/tokeninfo?access_token=%s", valAddr,accessToken); + Map header = new HashMap<>(); + String resp = HttpKit.get(url, new HashMap<>(), header); + FineLoggerFactory.getLogger().info("访问getUserInfo返回:{}", resp); + JSONObject entries = new JSONObject(resp); + return entries.getString("uid"); + } + + + private String getAccessToken(String code) throws IOException { + FLConfig xtlConfig = FLConfig.getInstance(); + String valAddr = xtlConfig.getValAddr(); + String appid = xtlConfig.getAppid(); + String loginClientSecret = xtlConfig.getLoginClientSecret(); + String url = String.format("%s/am/oauth2/access_token", valAddr); + Map header = new HashMap<>(); + Map params = new HashMap<>(); + params.put("client_id", appid); + String frurl = xtlConfig.getFrUrl() + "/url/oauth2/login"; + params.put("redirect_uri", frurl); + params.put("scope", "uid+cn+userIdCode"); + params.put("client_secret", loginClientSecret); + params.put("grant_type", "authorization_code"); + params.put("code", code); + String resp = HttpKit.post(url, params, "utf-8", "utf-8", header); + FineLoggerFactory.getLogger().info("访问getAccessToken返回:{}", resp); + JSONObject entries = new JSONObject(resp); + return entries.getString("access_token"); + } + + private String goAuth() { + FLConfig xtlConfig = FLConfig.getInstance(); + String valAddr = xtlConfig.getValAddr(); + String service = xtlConfig.getService(); + String appid = xtlConfig.getAppid(); + String frurl = xtlConfig.getFrUrl() + "/url/oauth2/login"; + String url = String.format("%s/am/oauth2/authorize?service=%s&" + + "response_type=code&client_id=%s&" + + "scope=uid+cn+userIdCode&redirect_uri=%s&decision=Allow", valAddr, service,appid, frurl); + return url; + } + + + private void sendRedirect(HttpServletResponse res, String url) { + res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); + res.setHeader("Location", url); + } + + private boolean login(HttpServletRequest req, HttpServletResponse res, String username) { + try { + String oldToken = TokenResource.COOKIE.getToken(req); + if ((oldToken == null) || (!checkTokenValid(req, oldToken, username))) { + HttpSession session = req.getSession(true); + String token = LoginService.getInstance().login(req, res, username); + session.setAttribute("fine_auth_token", token); + FineLoggerFactory.getLogger().error("fr CookieFilter is over with username is ###" + username); + return true; + } else { + FineLoggerFactory.getLogger().error("no need login: {}", username); + return true; + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + + private boolean checkTokenValid(HttpServletRequest req, String token, String currentUserName) { + try { + if (!ComparatorUtils.equals(currentUserName, JwtUtils.parseJWT(token).getSubject())) { + FineLoggerFactory.getLogger().info("username changed:" + currentUserName); + return false; + } else { + Device device = NetworkHelper.getDevice(req); + LoginService.getInstance().loginStatusValid(token, TerminalHandler.getTerminal(req, device)); + return true; + } + } catch (Exception var5) { + return false; + } + } + + +} diff --git a/src/main/resources/com/fr/plugin/web/logined.js b/src/main/resources/com/fr/plugin/web/logined.js new file mode 100644 index 0000000..c905ee6 --- /dev/null +++ b/src/main/resources/com/fr/plugin/web/logined.js @@ -0,0 +1,32 @@ +;(function ($) { + + BI.config("dec.user.setting.authentications", function (items) { + items.push({ + value: "oauth2", + text: "统一认证", + "@class": "com.fr.plugin.Oauth2Bean", + component: { + type: "dec.plugin.custom_oatuh2" + } + }); + return items; + }); + var Ldaps = BI.inherit(BI.Widget, { + + props: { + baseCls: "", + }, + render: function () { + var self = this, o = this.options; + return { + type: "bi.vertical", + bgap: 15, + items: [] + } + }, + getValue: function () { + return {}; + } + }); + BI.shortcut("dec.plugin.custom_oatuh2", Ldaps); +})(jQuery) \ No newline at end of file