NC6X单点登录设计文档说明
- 创业
- 2025-08-04 16:51:01

前言
因为业务场景需要,第三方系统有些工作需要经常到NC系统里做,如果每次去NC系统做业务单据,都需要反复登录,导致客户使用体验不是很好,所以需要开发实现从第三方系统单点登录到NC系统,提高客户满意度。
单点登录名词解释
单点登录(Single Sign On),简称为 SSO,是比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。
特别说明:本方案是基于用友集提供的【NC63单点登录方案说明文档】进行二次修改,本篇文章不仅是为了记录个人开发需要,也同样提供给广大开发者们。
1、详述方案说明想要单点登录到NC,首先需要在服务器端向NC服务器注册将要登录的用户的信息以及其他一些需要的信息,这些信息将被保存在NC服务器上,通过ssoKey进行关联映射。在完成注册信息后,客户端在登录时需要提供ssoKey,通过该值获得登录用户的相关信息,进入NC系统。
2、注册登录信息NC系统提供了一个Servlet来注册用户登录信息。访问该servlet的URL格式基本为:
http://host:port/service/ssoRegServlet,其后面可以跟随多个参数。
===参数信息===
【userCode】:
指定用户编码,该参数必须提供,不能省略。
【ssoKey】:
指定映射登录信息的键值,并在登录时需要提供该值。该值要求唯一,如果在注册时没有提供该值,NC系统会自动生成一个ssoKey的值,并在返回的Servlet流中输出该值。
【busiCenter】:
指定用户所属的账套编码,该值可以忽略。如果忽略该值,并且在多个账套中都存在userCode用户,那么会让终端用户选择账套。
【groupCode】:
指定登录的集团编码,该值可以忽略。
【langCode】:
指定登录的语种,该值可以忽略,默认为中文。
示例:
http://host:port/ service/ssoRegServlet?ssoKey=16354820401&userCode=zhangsan 这个URL表示将以用户zhangsan的身份登录,注册信息的键值为16354820401。 2.1、登录NC系统在完成了用户登录信息的注册后,客户端就可以以注册的ssoKey值来登录NC系统了,登录NC系统的ssoKey值以URL参数的形式提供。http://host:port/login.jsp?ssoKey=keyvalue。
对于前面的示例
http://host:port/ service/ssoRegServlet?ssoKey=16354820401&userCode=zhangsan
登录时的URL为:http://host:port/login.jsp?ssoKey=16354820401
2.2、根据功能节点打开NC界面打开nc系统的人员页面:ssoKey例如还是上面的令牌,nodeid=10140PSN是人员的功能注册编码
http://127.0.0.1/login.jsp?ssoKey=123459483230949&clienttype=portal&uiloader=nc.uap.lfw.applet.PortalUILoader&nodeid=10140PSN 2.3、自定义uiLoader打开NC任意界面在上一章节中是根据功能节点打开列表界面,那么如何打开单据卡片界面呢,或者如何打开流程卡片界面等等。所以需要自己开发一个uiLoader类进行处理,如下图所示,如何集成打开一个人员卡片界面。
开发过程:
2.3.1、 编写java类定义一个CustomPortalUILoader类,它继承了SSOLoader类。
示例代码:
package nc.demo.bx.uiloader; import java.awt.Component; import java.awt.Dimension; import nc.bs.framework.common.NCLocator; import nc.desktop.ui.WorkbenchEnvironment; import nc.funcnode.ui.FuncletInitData; import nc.funcnode.ui.FuncletWindowLauncher; import nc.itf.uap.bbd.func.IFuncRegisterQueryService; import nc.login.sso.ui.SSOLoader; import nc.sfbase.client.ClientToolKit; import nc.ui.bd.pub.BDFuncletInitData; import nc.ui.pub.msg.PfLinkData; import nc.ui.uap.sf.SFClientUtil; import nc.vo.bd.psn.PsndocVO; import nc.vo.pub.BusinessException; import nc.vo.sm.funcreg.FuncRegisterVO; public class CustomPortalUILoader extends SSOLoader { @Override public void appletInited() { //父窗体 Component parent = WorkbenchEnvironment.getInstance().getWorkbench(); String param = ClientToolKit.getAppletParam("nodeId"); String systemcode="local";//默认系统编码 //功能注册节点 String funCode=param; //人员pk String pk_psndoc = ClientToolKit.getAppletParam("pk_psndoc"); if(param.contains(":")){ funCode=param.split(":")[0]; systemcode=param.split(":")[1]; } IFuncRegisterQueryService service = NCLocator.getInstance().lookup(IFuncRegisterQueryService.class); FuncRegisterVO FrvO=null; try { FrvO = service.queryFunctionByCode(funCode);//功能节点编号 } catch (BusinessException e) { } //打开界面的三种方式如下: //**********第一种:打开流程单据卡片界面********************************************************************* // PfLinkData pflink = new PfLinkData(); // // pflink.setBillID("1001ZZ1000000000000Q"); // 本单据ID // // pflink.setBillType("SALE"); // 本单据类型 // // pflink.setSourceBillType("SALE"); // 上游单据类型 // // pflink.setPkOrg("0001ZZ1000000000074A"); // 公司 // // int height = ClientToolKit.getUserHeight()-40; // // int width = ClientToolKit.getUserWidth()-40; // FuncletWindowLauncher.openFuncNodeForceModalDialog(null, frvO,new FuncletInitData(1, pflink),null, true, new Dimension(width,height),null); // //**********第二种:打开档案卡片界面************************************************************************* PsndocVO psndocvo = new PsndocVO(); psndocvo.setPrimaryKey(pk_psndoc); BDFuncletInitData bdlinkdata = new BDFuncletInitData(null, 3, psndocvo); int height = ClientToolKit.getUserHeight()-40; int width = ClientToolKit.getUserWidth()-40; //模态窗体弹出对话打开 //FuncletWindowLauncher.openFuncNodeForceModalDialog(null, FrvO,new FuncletInitData(3, bdlinkdata),null, true, new Dimension(width,height),null); //非模态窗体弹出对话框框架打开 //FuncletWindowLauncher.openFuncNodeFrame(parent, FrvO, new FuncletInitData(3, bdlinkdata), null,false); //非模态窗体在原来窗体页签打开 FuncletWindowLauncher.openFuncNodeInTabbedPane(parent, FrvO, new FuncletInitData(3, bdlinkdata), null,false); //**********第三种:根据功能注册节点打开列表界面********************************************************************* //SFClientUtil.open(parent, funCode); String[] script = new String[]{"if(opener)opener.ncNodeAppletMap.put('"+systemcode+"',findNCApplet())"}; ClientToolKit.callJavaScript("eval", script); } } 2.3.2、部署部署到nchome中对用模块的client中,我的测试模块是lfwdemo。如图:
2.3.3、测试1、首先令牌注册,在IE浏览器中,输入下面url。注意:帐套编码busiCente最好是填写上,否则在登录的时候要求选择帐套。
http://127.0.0.1/service/ssoRegServlet?ssoKey=123459483230949&userCode=admin&busiCenter=dev
2、 然后在IE浏览器中,输入下面url,就可以直接打开人员的卡片界面了
http://127.0.0.1/login.jsp?ssoKey=123459483230949&clienttype=portal&uiloader=nc.demo.bx.uiloader.CustomPortalUILoader&nodeid=10140PSN&pk_psndoc=1001ZZ1000000000000Q
3、单点登录配置文件详述单点登录的配置文件路径为${NCHOME}\ierp\sf\ssoConfig.xml,该文件默认的内容如下。
<?xml version="1.0" encoding="UTF-8"?> <SSOConfig> <regTimeOut>200</regTimeOut> <authenticator classname="nc.sso.bs.DefaultSSOAuthenticator"> <listParam key="IPAddress"> <string>127.0.0.1</string> </listParam> </authenticator> </SSOConfig>在这个配置文件中主要可以配置两个信息
1 )注册信息的超时设置
2 )注册时的验证处理类
3.1、注册信息的超时设置当用户注册完用户的登录信息后,在还没有进行登录之前,注册的登录信息将保存在NC系统中。在用户开始登录NC时,该注册信息才会从NC系统中被清除。
如果由于某种原因,用户没有触发登录操作,那么注册信息将在超时后,被系统自动清除掉,这个超时的时间值的配置是在配置文件中的<regTimeOut>标签项配置的,单位为秒。默认值为200秒。
如果用户是在超时以后才登录NC,那么登录将会失败,会提示找不到注册信息。
3.2、注册时的验证处理由于只要向NC系统中注册了用户的登录信息,就可以单点登录到NC。所以从安全考虑,需要再注册用户的登录信息时进行权限验证。
单点登录注册时采用的验证类的配置是在配置文件中的< authenticator >标签项配置的。
通过classname属性指定验证类的类名,该类必须实现nc.sso.bs.ISSOAuthenticator接口。
public interface ISSOAuthenticator { public void authenticate(HttpServletRequest request) throws Exception; }默认的验证类为nc.sso.bs.DefaultSSOAuthenticator,该验证类将检查注册的URL的来源主机的ip地址是否在其所配置的合法ip地址的范围内,如果是,则允许注册,否则,将拒绝注册。
如果希望提供更加安全的验证处理,可以通过实现nc.sso.bs.ISSOAuthenticato接口并注册在配置文件中即可。
3.3、AbstractSSOAuthenticatorAbstractSSOAuthenticator类是一个实现了ISSOAuthenticato接口的抽象类,他提供了获取参数的方法String getValue(String key)和String[] getValues(String key)这些参数是在配置文件中进行配置的。所以在实现注册时的验证处理类时,如果需要能拥有获取配置文件中参数的功能,可以直接继承AbstractSSOAuthenticator类。
参数的配置提供两种标签:
1、字符串参数的配置标签
<param>:<param key=”key1” value=”value1”>
这类参数值可以通过String getValue(String key)方法获取
2、字符串数组参数的配置标签
<listParam>: <listParam key="key"> <string>value1</string> <string>value2</string> <string>value3</string> </listParam>这类参数值可以通过String[] getValues(String key)方法获取。
NC6X单点登录设计文档说明由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“NC6X单点登录设计文档说明”