NC6X单点登录设计文档说明

 前言

  因为业务场景需要,第三方系统有些工作需要经常到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 {@Overridepublic void appletInited() {//父窗体Component parent = WorkbenchEnvironment.getInstance().getWorkbench();String param = ClientToolKit.getAppletParam("nodeId");String systemcode="local";//默认系统编码//功能注册节点String funCode=param;//人员pkString 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、AbstractSSOAuthenticator

AbstractSSOAuthenticator类是一个实现了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)方法获取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2773889.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【c语言】深入理解指针(2)

1. 字符指针变量 可以利用字符指针存放字符数组来间接存放字符串。 int main() {char arr[10] "abcdef";char* p arr;printf("p %s\n", p);return 0; } 那我们可不可以直接给字符指针存放字符串呢&#xff1f; int main() {char* p1 "abcde…

【C#】.net core 6.0 创建默认Web应用,以及默认结构讲解,适合初学者

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

Octave实现位置式PID算法

由于Matlab不让用&#xff0c;只能“你不让爷用&#xff0c;爷就用别的”&#xff0c;选择开源的Octave以及scilab进行相关领域的学习。Octave的代码和Matlab几乎是100%相同的&#xff0c;只有一些专用的包的函数&#xff0c;可能有些还没来得及写&#xff0c;或者有些差异。但…

计算机网络概念、组成、功能和分类

文章目录 概要1.怎么学习计算机网络2.概念3.功能、组成4.工作方式、功能组成5.分类 概要 概念、组成、功能和分类 1.怎么学习计算机网络 2.概念 通信设备&#xff1a;比如路由器、路由器 线路&#xff1a;将系统和通信设备两者联系的介质之类的 计算机网络是互连的、自治的的计…

如何用DT浏览器建立视频播放系统

在DT浏览器官方网站下载最新版软件&#xff0c;安装&#xff0c;在DT浏览器首页点视频直播&#xff0c;软件会自动检测手机相册里的视频并且显示出来&#xff0c;选择需要播放的视频在直播间里播放。如果要建立节目单&#xff0c;需要在服务器上把播放顺序&#xff0c;视频名称…

一起玩儿物联网人工智能小车(ESP32)——57. SPI总线协议初探(一)

摘要&#xff1a;介绍SPI总线的基本知识 前面已经学习过IIC总线协议&#xff0c;今天开始介绍另一个总线协议——SPI。SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是由Motorola提出的一种高速、全双工、同步的通信总线。并且在芯片的管脚…

Oracle 面试题 | 17.精选Oracle高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

(每日持续更新)jdk api之ObjectInputFilter.Status基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

市场复盘总结 20240207

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 75% 最常用…

JavaScript中call、apply、bind方法的应用与区别

在JavaScript中&#xff0c;call、apply和bind是函数的三个重要方法&#xff0c;它们虽然功能不同&#xff0c;但都可以用来改变函数的执行上下文或者传递参数。本文将分别介绍call、apply和bind方法的应用和区别&#xff0c;并附带示例代码。 一、call方法 call方法的作用是…

移动光猫gs3101超级密码及改桥接模式教程

文章目录 超级管理员账号改桥接模式路由器连接光猫&#xff0c;PPPOE拨号即可&#xff01;附录&#xff1a;如果需要改桥接的话不知道拨号密码咋办打开光猫Telnet功能Telnet 登录 参考文章 移动光猫吉比特GS3101超级账号获取更改桥接 移动光猫gs3101超级密码及改桥接模式教程 …

分享一下 uniapp 打包安卓apk

首先需要安装 Java 环境&#xff0c;这里就不做解释了 第二步&#xff1a;打开 mac 终端 / cmd 命令行工具 使用keytool -genkey命令生成证书 keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore *testalias 是证书别名&am…

华大基因PMseq病原微生物高通量基因检测产品耐药数据库持续

23年肺炎支原体感染的患者数量持续上升&#xff0c;与此同时&#xff0c;由肺炎支原体感染引发的住院患者数量也在迅速增加。这就导致近期儿科和发热门诊都处于床位爆满状态。而在疑难危重的肺炎患者中&#xff0c;肺炎支原体的检出率也在不断提高。华大基因PM Online线上数据管…

ELAdmin 的 CRUD

数据表结构 弄个测试的数据表&#xff0c;不同类型的几个字段&#xff0c;表名位 mp_reply。 生成代码 ELAdmin 可以自动生成代码。 左侧目录系统工具–代码生成&#xff0c;点开以后可以看到上面创建的数据表mp_reply&#xff0c;点击配置。 进入的页面内容有两部分&#…

【Linux笔记】缓冲区的概念到标准库的模拟实现

一、缓冲区 “缓冲区”这个概念相信大家或多或少都听说过&#xff0c;大家其实在C语言阶段就已经接触到“缓冲区”这个东西&#xff0c;但是相信大家在C语言阶段并没有真正弄懂缓冲区到底是个什么东西&#xff0c;也相信大家在C语言阶段也因为缓冲区的问题写出过各种bug。 其…

Blender教程(基础)-顶点的移动、滑移-16

一、顶点的移动与缩放 ShiftA新建柱体、切换到编辑模式 点模式下&#xff0c;选择一个顶点、选择移动&#xff08;GZ&#xff09;&#xff0c;发现顶点严Z轴移动&#xff0c;如下图所示 GY 按数字键盘7切换视图&#xff0c;选择这个面的所有顶点 按S把面缩放大 Ctrl…

TCP相关知识点

TCP相关知识点 参考&#xff1a; 《计算机网络》 (建议收藏)TCP协议灵魂之问&#xff0c;巩固你的网路底层基础 关于 TCP 三次握手和四次挥手&#xff0c;满分回答在此 (值得看) TCP处于网络体系结构中的运输层。 运输层主要为应用进程提供端到端的逻辑通信&#xff0c;然后对…

双非本科准备秋招(19.1)—— Synchronized优化

轻量级锁 流程 一个对象虽然有多线程加锁&#xff0c;但是加锁时间是错开的&#xff0c;那么可以用轻量级锁优化。 语法还是synchronized&#xff0c;只是对使用者是透明的。 static final Object obj new Object(); public static void method1() {synchronized( obj ) {//…

代码随想录算法训练营第42天 | 01背包理论基础 416.分割等和子集

01背包理论基础 问题定义&#xff1a;有n件物品和一个能装重量为w的背包&#xff0c;第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i]。每件物品只能用一次&#xff0c;求解将哪些物品装入背包获得的总价值最大。dp数组含义&#xff1a;dp[i][j] 表示从下标为 [0…

(篇九)MySQL常用内置函数

目录 ⌛数学函数 ⌛字符串函数 ⌛聚合函数 ⌛日期函数 &#x1f4d0;获取当前时间 &#x1f4d0;获取时间的某些内容 &#x1f4d0;​编辑 &#x1f4d0;格式化函数 &#x1f4cf;format类型&#xff1a; ⌛系统信息函数 ⌛类型转换函数 数学函数 字符串函数 聚合函…