启动插件校验机制实现免登录功能,【简单通行证】方式

栏目:云星空知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

启动插件校验机制实现免登录功能,【简单通行证】方式

原始地址:https://vip.kingdee.com/article/37406 


启动插件校验机制实现免登录功能,【简单通行证】方式

特别敬告:本例子中采用的参数映射法,强烈推荐采用V2版本的参数协议,具有更强的扩展性。V2协议参看链接】 

V2协议参考:【启动插件校验机制实现免登录功能-支持云之家集成与JSON参数



1、背景
    在一些第三方系统中希望集成K/3 Cloud系统,在第三方系统登录后能直接进入K/3 Cloud系统,而无须再次通过登录界面录入数据中心,用户名和密码,这时基于安全性需要,需要提供客制化的会话串来实现与第三方系统之间的映射校验。

2、实现
    在K/3 Cloud客户端或者Web程序启动时,调用StartAppVerifyService服务进行校验,校验可配置用户定制逻辑组件接入进行校验。如果允许接入,则按用户定制组件逻辑实现K/3 Cloud登录校验,校验通过,则直接按指定用户进入K/3 Cloud系统主控界面。

3、客户定制逻辑组件编写详细代码参考6
     3.1、新建C#组件库工程,配置为NetFramework4.0支持。
     3.2、引用K/3 Cloud WebSite/Bin目录下的如下4个组件:
Kingdee.BOS.dll, 
Kingdee.BOS.DataEntity.dll, 
Kingdee.BOS.ServiceFacade.ServicesStub.dll,
Kingdee.BOS.ServiceFacade.KDServiceFx.dll。
     3.3、添加新类文件,命名为MacVerify(例如),并继承接口   Kingdee.BOS.ServiceFacade.ServicesStub.StartAppVerifyServiceBase抽象类,实现接口行数 StartAppResult Verify(KDServiceContext context, string ipmac)。其中ipmac数据会包含属性customArgs,该属性既是客制化参数,由第三方应用传入,传入方式如下三种方式, 组件中的customArgs参数内容来源于下面定制参数的ud入口参数内容
        /// 例如:
        /// 【映射用户登入信息方式】

        /// WEB的Silverlight: http://xxxx/k3cloud/silverlight/index.aspx?ud=|563073d2b90b4f|Developer|hr|cf6e86aed7d40b1534cf9a1ea557a073626a30ac|1458613257|2052

        /// WEB的HTML5:http://xxxx/k3cloud/html5/index.aspx?ud=|563073d2b90b4f|Developer|hr|cf6e86aed7d40b1534cf9a1ea557a073626a30ac|1458613257|2052



        /// 简单通行证方式:ud=|dbid|username|appid|signeddata|timestamp[|lcid], 演示可以是明文,正式上线最好做数据加密。
        ///  简单通行证的上面密码协议格式自定义,在插件中进行二开解析

     3.4、MacVerify中可定制客户逻辑,最终返回 StartAppReslut对象即可。如果ResultType==Success正常登录,如果ResultType==Failure,则提示Message中的文本内容。通过customArgs进行数据中心,用户匹配,再调用基类的DoLoginCore方法实现K/3 Cloud的登录校验,或获取返回值的UserToken到StartAppReslut对象中。返回不需处理该UserToken,直接返回StartAppReslut对象即可实现自动登录了。
     3.5、需要特别注意的是,不要在插件中直接throw new Exception(),要用返回方式2提示退出,或者方式4提示重定向来显示错误的内容,包括 exception.Message exception.StackTrace;   一旦插件throw异常,框架会忽略异常后进入登录界面。

     3.6、更多其他信息参考下面文章
    https://vip.kingdee.com/article/8928


4、部署
    4.1、拷贝插件到应用服务器的站点目录WebSite/Bin目录下。
    4.2、修改配置文件应用服务器的站点目录WebSite/App_Data/Common.config,在appsettings节点下增加如下项目:
<!--启动服务插件-->
<add key ="StartAppPlugin" 

value="Kingdee.BOS.ServiceFacade.StartApp.MacVerify,Kingdee.BOS.ServiceFacade.StartApp" />
<!--用户参数配置,默认跟随系统-->
<add key ="StartAppPluginUDConfig" value="{encoding:'utf-8'}" />
  
特别注意

 * 注意是应用服务器,不是管理中心服务器;

 * 不要只写类名,组件名就不写了。上面value的格式是【类的全名,组件名】   
 * Kingdee.BOS.ServiceFacade.StartApp这个组件和其中的类仅是功能测试和演示使用。

 * 二次开发的插件不要使用Kingdee, Kingdee.BOS, Kingdee.BOS.ServiceFacade,  Kingdee.BOS.ServiceFacade.StartApp.MacVerify  这些命名空间和类名。

 * 如果想直接使用这个演示组件内容,建议拷贝文章中的代码内容后,修改命名空间和类名为贵公司的命名规则,不用使用Kingdee命名空间,避免后续功能补丁升级时的覆盖影响。           
  

5、第三方接入方式
  实现插件启动登录逻辑(参考后面6的插件实现)后,即可用下面方式实现免登录直接进入K/3 Cloud系统主控。
  实现登录服务处理接口,在程序启动界面加入参数ud=|dbid|username|appid|signeddata|timestamp[|lcid]即可实现自动用[用户登录[数据中心
  例如:
    WEB的Silverlight: http://xxxx/k3cloud/silverlight/index.aspx?[url=]ud=|dbid|username|appid|signeddata|timestamp[|lcid][/url]
    WEB的HTML5:http://xxxx/k3cloud/html5/index.aspx?ud=|dbid|username|appid|signeddata|timestamp[|lcid]


6、第三方接入插件代码编写

按【3、客户定制逻辑组件编写】完成插件工程配置后,修改启动插件,继承基类StartAppVerifyServiceBase,并实现StartAppResult Verify(KDServiceContext context, string ipmac)接口;

【例子代码如下:】在上一个姐妹篇中【利用启动插件校验机制实现免登录功能,实现跨系...】的例子中增加下面函数,实现简单通行证,就可以不需要知道ERP系统的密码了。

using Kingdee.BOS.Util;

        /// <summary>
        /// 实现登录校验的例子的私有函数::简单通行证方式
        /// 简单通行证方式:ud=|dbid|username|appid|signeddata|timestamp[|lcid], 演示可以是明文,正式上线最好进行编码加密。
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ret"></param>
        /// <param name="data"></param>
        private void VerifyLoginBySimplePassport(KDServiceContext context, StartAppResult ret, JSONObject data)
        {
            //实现自动登录功能
            var customArgs = data.GetValue<string>("customArgs", "");//ud用户定义参数将会传递到服务端插件的customArgs中
            var isAutoLogin = !string.IsNullOrWhiteSpace(customArgs);
            var userInfoStr = customArgs;
            if (!userInfoStr.StartsWith("|"))
            {
                // 如果参数没有使用Base64编码,这段解码逻辑可以去掉
                var arg = userInfoStr.Base64ToBytes();
                userInfoStr = UTF8Encoding.Default.GetString(arg); //KDHttpUtility.RequestUtility.HtmlDecode(userInfoStr);
            }
            var userInfo = userInfoStr.Split('|');
            //协议为6个参数|dbid|username|appid|signeddata|timestamp[|lcid]
            if (isAutoLogin && userInfo.Length < 6)
            {
                isAutoLogin = false;
                ret.ResultType = StartAppResultType.Failure;
                ret.Message = "自动登陆参数格式错误!";
            }

            if (isAutoLogin && context != null)
            {
                try
                {
                    //包括用户名、密码和数据库id,已经对应的语种id
                    var dbid = userInfo[1];
                    var userName = userInfo[2];
                    var appId = userInfo[3];
                    var signedData = userInfo[4];
                    long timestamp = 0; long.TryParse( userInfo[5],out timestamp);
                    var lcid = 2052;
                    if (userInfo.Length > 6 && !int.TryParse(userInfo[6], out lcid))
                    {
                        lcid = 2052;
                    }
                    var password = "888888";

                    var pluginLoginInfo = new PluginLoginInfo()
                    {
                        PasswordIsEncrypted = false,
                        Password = password,//任意字符串,但不能为空
                        // 此处是强制使用【简单证书】登陆
                        AuthenticateType = AuthenticationType.SimplePassportAuthentication,
                        ClientInfo = GetClientInfo(context, data),
                        AcctID = dbid, //AcctID如果传递,将不再通过AcctName查找AcctID了。
                        //LoginType = PluginLoginType.Common, //默认为用户名密码的通用登录方式。
                        //AcctName = dbid,//AcctID如果不传递,将通过AcctName查找AcctID。
                        Username = userName,
                        Lcid = lcid,
                        AppId = appId,
                        Timestamp = timestamp,
                        ////appSecret 公钥字符串,来自administrator管理中第三方系统登陆授权功能分配的加密钥匙
                        //Kingdee.BOS.Util.SHA1Util.GetSignature(
                        //  new string[] { 
                        //      dbId, usserName, appId, appSecret, timestamp.ToString() 
                        //  });
                        SignedData = signedData
                    };

                    //调用基类工具方法实现登录验证,并返回ret.UserToken,给客户端实现自动登录
                    DoLoginCore(context, ret, pluginLoginInfo);                     
                    // 登录后的参数传入,具体使用参考【自动打开单据

                    /*

                    //用协议V2的json方式就无须这样打开默认单据,下面语句可以忽略
                    if (!string.IsNullOrWhiteSpace(ret.SessionId))
                    {
                        var isoKey = ret.SessionId "_AutoLoginArgs";
                        //登陆成功后,加入自定义参数
                        //HttpContext.Current.Application.Set(isoKey, "PUR_PurchaseOrder|100001");
                    }*/
                }
                catch (Exception ex)
                {
                    ret.ResultType = StartAppResultType.Failure;
                    ret.FailureCallBackType = StartAppResultCallBackType.Message;
                    ret.Message = ex.Message "\r\n" ex.StackTrace;
                }
            }
        }


7、协议内容解析(演示例子中的参数协议,具体实际应用可以自定义,但基本参数不能缺少):
参数格式:ud=|dbid|username|appid|signeddata|timestamp[|lcid],其中ud为参数名;协议格式:|dbid|username|appid|signeddata|timestamp[|lcid]
dbid:数据中心的ID;username:用户名称;
appid:应用程序ID,通过Administrator登录数据中心后,在【系统管理】分类的【第三方系统登录授权】功能里面进行新增维护;
signeddata:数据签名串,通过公钥和用户数据进行运算得到,在后面有详细说明; 
            // signeddata公钥字符串,来自administrator管理中【第三方系统登陆授权】功能分配的加密钥匙
            // 参数中secret为【第三方系统登陆授权】中自动分配的【应用密钥】
            var signedData = Kingdee.BOS.Util.SHA1Util.GetSignature(
              new string[] { 
                  dbId, userName, appId, secret, timeStamp.ToString() 
              });
timestamp:登录时间戳(Unix时间戳,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数);
lcid(可选):语言ID,中文2052(默认),英文1033,繁体3076
.
ps: 如果使用的是其他语言,比如java等,可以参照下面算法生成数据签名串[signedData]:


        /// <summary>
        /// SHA1签名
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static string GetSignature(string[] arr)
        {
            //1. 将数组进行排序
            //2. 将数组拼接成一个字符串进行sha1加密
            arr = arr.OrderBy(z => z).ToArray();
            var arrString = string.Join("", arr);
            var sha1 = SHA1.Create();
            var sha1Arr = sha1.ComputeHash(Encoding.UTF8.GetBytes(arrString));
            StringBuilder enText = new StringBuilder();
            foreach (var b in sha1Arr)
            {
                enText.AppendFormat("{0:x2}", b);
            }

            return enText.ToString();
        }





8,管理第三方系统登陆授权
1、Administrator登陆K/3 Cloud数据中心;
2、打开【系统管理- 第三方系统登陆授权】功能;

云之家图片20181229135302.webp


3、新增或修改对应外部接入系统的密钥和APPID;如下图:

云之家图片20181229135317.webp




--附录---------------- 参考帖子区 ----------------------

星空第三方免登资料参考链接

https://vip.kingdee.com/article/221201966503051264 


----------------------------

编辑于2020年4月8日 10:49:15

启动插件校验机制实现免登录功能,【简单通行证】方式

原始地址:https://vip.kingdee.com/article/37406 启动插件校验机制实现免登录功能,【简单通行证】方式【特别敬告:本例子中采用的参数映...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息