Ecology异构系统认证流程时序图
认证流程时序图
认证流程简图
一、ECOLOGY系统配置
1、配置接口白名单
在ecology系统代码目录中找到以下配置文件:ecology/WEB-INF/prop/weaver_session_filter.properties
checkurl=/api/hrm/emmanager;/api/userPhrase;uncheckurl=/api/ec/dev/app/getCheckSystemInfo;/api/ec/dev/app/emjoin;unchecksessionurl=/api/ec/dev/util/accesspage;.../api/loginportal/element/;/api/edc/fillin/;
在unchecksessionurl=
后面添加/api/ec/dev/auth/regist;/api/ec/dev/auth/applytoken;
配置后的白名单需要重启生效
2、发放/生成许可证(appid)
就是向数据库插入一条记录,之后访问的话会匹配这条记录,用于身份认证
在ecology系统数据库执行以下脚本示例(请不要直接使用示例中的数据!):
INSERT INTO ECOLOGY_BIZ_EC(ID,APPID,NAME) VALUES('123456','test','上海泛微网络科技股份有限公司');COMMIT;
字段描述:
- ID:数据库主键。保证与其它系统发放的许可证在数据库中的主键标识不冲突即可(
对应示例:123456
) - APPID:许可证号码。最终发放给异构系统的许可证号码,多个许可证号码保证唯一(
对应示例:test
) - NAME:许可证名称。用于快速辨识许可证发放系统(
对应示例:上海泛微网络科技股份有限公司
)
3、限制许可证使用ip地址
在ecology系统代码目录中找到以下配置文件:ecology/WEB-INF/prop/weaver_rest_token.properties
# 限制Rest API Token Invoke注册端IP地址,多个IP地址之间用逗号分隔# 例如:allowIp=127.0.0.1,192.168.0.1,172.10.0.1,10.10.10.01allowIp=
在allowIp=
后面添加客户调用方服务器实际的ip地址(不设置将代表不限制任何ip,生产环境建议设置)
二、异构系统编码实现认证
1、引入RSA加密算法工具jar包到异构系统
- java开发语言的客户可以直接在ecology系统代码目录中找到
ecology/WEB-INF/lib/hutool-all-5.3.0.jar
文件引入到异构系统项目资源目录下。或自行引用hutool https://hutool.cn/ - C#开发语言异构系统的rsa算法案例:下载案例
- 其他开发语言的异构系统请自行查询一下底层库实现的rsa算法。
在线测试rsa算法加解密网站:在线RSA测试
关于RSA算法请参考百度百科:RSA算法
2、JAVA演示代码(下载演示代码)
package weaver.demo;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/*** Token认证测试** 认证过程主要采用RSA非对称加密算法** @author tzf 2020/6/9*/
public class MainTest {/*** 模拟缓存服务*/private static final Map<String,String> SYSTEM_CACHE = new HashMap <>();/*** ecology系统发放的授权许可证(appid)*/private static final String APPID = "62acf88c-55d0-465c-b08d-99cd36271231";public static void main(String[] args) {testRestful("http://10.10.10.40","/api/system/appmanage/route",null);}/*** 第一步:** 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息*/public static Map<String,Object> testRegist(String address){//获取当前系统RSA加密的公钥RSA rsa = new RSA();String publicKey = rsa.getPublicKeyBase64();String privateKey = rsa.getPrivateKeyBase64();// 客户端RSA私钥SYSTEM_CACHE.put("LOCAL_PRIVATE_KEY",privateKey);// 客户端RSA公钥SYSTEM_CACHE.put("LOCAL_PUBLIC_KEY",publicKey);//调用ECOLOGY系统接口进行注册String data = HttpRequest.post(address + "/api/ec/dev/auth/regist").header("appid",APPID).header("cpk",publicKey).timeout(2000).execute().body();// 打印ECOLOGY响应信息System.out.println("testRegist():"+data);Map<String,Object> datas = JSONUtil.parseObj(data);//ECOLOGY返回的系统公钥SYSTEM_CACHE.put("SERVER_PUBLIC_KEY",StrUtil.nullToEmpty((String)datas.get("spk")));//ECOLOGY返回的系统密钥SYSTEM_CACHE.put("SERVER_SECRET",StrUtil.nullToEmpty((String)datas.get("secrit")));return datas;}/*** 第二步:** 通过第一步中注册系统返回信息进行获取token信息*/public static Map<String,Object> testGetoken(String address){// 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息String secret = SYSTEM_CACHE.get("SERVER_SECRET");String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");// 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新if (Objects.isNull(secret)||Objects.isNull(spk)){testRegist(address);// 重新获取最新ECOLOGY系统公钥和Secret信息secret = SYSTEM_CACHE.get("SERVER_SECRET");spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");}// 公钥加密,所以RSA对象私钥为nullRSA rsa = new RSA(null,spk);//对秘钥进行加密传输,防止篡改数据String encryptSecret = rsa.encryptBase64(secret,CharsetUtil.CHARSET_UTF_8,KeyType.PublicKey);//调用ECOLOGY系统接口进行注册String data = HttpRequest.post(address+ "/api/ec/dev/auth/applytoken").header("appid",APPID).header("secret",encryptSecret).header("time","3600").execute().body();System.out.println("testGetoken():"+data);Map<String,Object> datas = JSONUtil.parseObj(data);//ECOLOGY返回的token// TODO 为Token缓存设置过期时间SYSTEM_CACHE.put("SERVER_TOKEN",StrUtil.nullToEmpty((String)datas.get("token")));return datas;}/*** 第三步:** 调用ecology系统的rest接口,请求头部带上token和用户标识认证信息** @param address ecology系统地址* @param api rest api 接口地址(该测试代码仅支持GET请求)* @param jsonParams 请求参数json串** 注意:ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8"*/public static String testRestful(String address,String api,String jsonParams){//ECOLOGY返回的tokenString token= SYSTEM_CACHE.get("SERVER_TOKEN");if (StrUtil.isEmpty(token)){token = (String) testGetoken(address).get("token");}String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");//封装请求头参数RSA rsa = new RSA(null,spk);//对用户信息进行加密传输,暂仅支持传输OA用户IDString encryptUserid = rsa.encryptBase64("1",CharsetUtil.CHARSET_UTF_8,KeyType.PublicKey);//调用ECOLOGY系统接口,注意此处的disableCookie,可翻阅hutool的文档查看String data = HttpRequest.disableCookie().get(address + api).header("appid",APPID).header("token",token).header("userid",encryptUserid).body(jsonParams).execute().body();System.out.println("testRestful():"+data);return data;}
}
testRegist():{"msg":"ok","code":0,"msgShowType":"none","secrit":"c8b987ff-ce36-4fbe-bac5-98370b1d5c5a","secret":"c8b987ff-ce36-4fbe-bac5-98370b1d5c5a","status":true,"spk":"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCAbZETaIipqH7puERgJ6VVkBGKOCK+JOfr7+A+VfobRLGeXVkuCRzFj0RhlqlODzCjEff6rm0WDrcfAM6BxfjCciCKx2EXqjklfgZyY/gGf8PYfVmPG55k37edba4MpG+R1fcMtsB5qRHTpEVfoVBlr8ys1VhA/7dv+JLwg5B+FQIDAQAB"}
testGetoken():{"msg":"获取成功!","code":0,"msgShowType":"none","status":true,"token":"7099a965-7ef4-4e2d-a1e2-a4d66a10e945"}
testRestful():{"schema":"http","code":0,"port":80,"msgShowType":"none","ip":"10.10.10.40","host":"192.168.42.163","type":"1","url":"/spa/coms/static4mobile/index.html#/menu-preview?id=appPage_ooxtkh&checkAccess=1","status":true}
三、API文档在线说明(初学者从这里开始)
第0步:获取postman请求模板、下载演示视频
(下载请求模板)
(下载演示视频)
3.1、第一步:向OA系统发送许可证信息进行注册认证(只需要注册一次即可,后面多次注册会更新密钥导致解密失败,最新版本的ecology已经隔离出注册和更新接口)
- 许可证注册接口
请求URL:
http://xx.com/api/ec/dev/auth/regist
请求方式:
- POST
请求头部参数(request headers):
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
appid | 是 | string | 许可证号码 |
loginid | 是 | string | OA系统账号登录名(KB1906版本及以上已废除) |
pwd | 是 | string | 账号密码加密后的密文(KB1906版本及以上已废除) |
cpk | 是 | string | 异构系统公钥(无用,但是必传,可传123) |
请求体参数(request body):
无
返回示例(response body)
{ "msg": "ok", "errcode": "0", "code": 0, "msgShowType": "none", "secrit": "e0ab4a73-e9c6-4ae5-9dac-f21a7807991a", "errmsg": "ok", "status": true, "spk": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNIfHNjAvtvkSKtAj79mkHOk5/bDwrGVykRJ7saI1oLHPp8lEQjBP5Ae4Te5chzflLLEj4WP24JnY2ahzb8xnPU/HNt/lwhykjoxVPoczdlXL4jcdMuvgitgCQdrqPgtpzrKNOoKbTz9vagMl0LbzGlSzGPF4PAlGDw+OrgOMsiWXyG1EsQWOW5zfwnnGfvnPZlpSKfDKT3m+9oPL/cWQv6FU1A1kHO4ADT+Np8Q2n33mMJC1Sc+YiFjNIblGoB0AME7M0hb+Ln4b+n+23jsBBeZhfBdmRdLY31AALWIuJH1+8KZvaaMS0OwkBdCfZhF4chWYSRAV4yjCx19Ax/wBQIDAQAB"}
返回参数说明
参数名 | 类型 | 说明 |
---|---|---|
status | boolean | 响应状态。true:成功,false:失败 |
code | String | 响应码。0代表成功 |
errcode | String | 错误码。0代表成功(可忽略) |
msg | String | 响应信息 |
msgShowType | String | 信息显示类型。默认“none” |
secrit(或secret) | String | 秘钥信息。注意此处secrit单词拼写错误(原词为:secret),请使用 secrit获取结果 |
spk | String | 系统公钥信息 |
返回错误示例一
{ "msg": "ok", "errcode": "1", "code": -1, "msgShowType": "none", "errmsg": "passowrd error:null & sysadmin", "status": false}
返回错误示例二:注册失败没有找到正确APPID
问题原因:
1.appid填写错误(有可能是换行,加入了特殊字符导致的问题,建议使用postman或其它工具先测试)
2.在数据库执行上面没有提交事务(没有使用commit)
3.请求服务器对应的数据库并不是插入记录的数据库
4.缓存问题,需要清理缓存解决:oa地址+/commcache/cacheMonitor.jsp
{ "msg": "ok", "errcode": "1", "code": 0, "msgShowType": "none", "errmsg": "注册失败没有在找到正确的APPID:EEAA5436-7577-4BE0-8C6C-89E9D888", "status": false}
3.2、第二步:向OA系统发送获取token请求
- 获取token接口
请求URL:
http://xx.com/api/ec/dev/auth/applytoken
请求方式:
- POST
请求头部参数(request headers):
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
appid | 是 | string | 许可证号码 |
time | 否 | int | token过期时间(单位:秒,不传默认1800秒,也就是30分钟过期) |
secret | 是 | string | 通过spk(第一步传回)对secret(第一步传回)进行加密后的密文。(注意此处参数名单词拼写正确)(通过下面的加密算法网站对数据进行加密处理) |
在线RSA加密算法网站:在线RSA测试
关于RSA算法请参考百度百科:RSA算法
请求体参数(request body):无
返回示例
{ "msg": "获取成功!", "code": 0, "msgShowType": "none", "status": true, "token": "770a10d8-0b15-492b-a614-b2c537b512e5"}
返回参数说明
参数名 | 类型 | 说明 |
---|---|---|
status | boolean | 响应状态。true:成功,false:失败 |
code | String | 响应码。0代表成功 |
msg | String | 响应信息 |
msgShowType | String | 信息显示类型。默认“none” |
token | String | 认证通过的token信息。(默认30分钟内有效) |
返回错误示例一
- 说明appid填写错误,请仔细检查后台数据库ecology_biz_ec表中是否有此appid
{ "msg": "认证信息错误!", "code": -1, "msgShowType": "none", "status": false}
返回错误示例二
- 第一步接口再次请求时会更新原有密钥,导致密钥不匹配解密失败,因此第一步获取密钥时只获取一次即可,后面每次获取都会更新原有密钥,调用方应妥善保管好appid、secret、spk等信息,如果密钥被更新,新版本kb已经将密钥获取和更新分开,可升级至最新版本kb
- 经过再三检查发现怎么调用都是解密失败,特别是前一段时间能用,集成北森jar包、更新kb之后突然就不能用了,这可能是因为jar包冲突导致的问题,请跳转到“四”获取jar包冲突的解决方案
{ "msg": "解密失败!", "code": -1, "msgShowType": "none", "status": false}
3.3、第三步:通过token的方式认证调用ECOLOGY系统业务接口
请求URL:
http://xx.com/api/接口地址
请求方式:
- GET | POST | PUT | DELETE
请求头部参数:
说明:userid必填!否则将无法通过token认证;另外
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
token | 是 | string | token信息 |
appid | 是 | string | 许可证号码 |
userid | 是 | string | 通过第一步注册许可时返回spk公钥对userid进行加密生成的密文 |
skipsession | 否 | string | 是否跳过session拦截(用于白名单接口),1代表是,0代表否(缺省) |
Content-Type | 否 | string | POST请求必须设置Context-Type为”application/x-www-form-urlencoded; charset=utf-8” |
接口参数:按照相关业务模块接口规范编写
返回示例
{ "msg": "ok", "code": 0, "msgShowType": "none", "status": true}
返回参数说明
参数名 | 类型 | 说明 |
---|---|---|
status | boolean | 响应状态。true:成功,false:失败 |
code | String | 响应码。0代表成功 |
msg | String | 响应信息 |
msgShowType | String | 信息显示类型。默认“none” |
返回错误示例一
- 如果客户是集群环境,并且经常复现此类错误,请检查redis是否正常,如果没有使用redis,我这边可以修改为只使用数据库进行存储token,防止复现
- 正常调用出现此类错误的,可以使用postman进行测试,看看token是否很快过期,token很快就过期可能是因为缓存问题,我这边可以修改为只使用数据库进行存储token,防止复现.
{ "msg": "token:不存在或者超时a25ed7ba-6027-424d-96ec-99daef56a51d", "code": -1, "msgShowType": "none", "status": false}
返回错误示例二
密钥不匹配返回500并附带图片:密钥不匹配导致的问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qwcRhd3P-1670554628215)(C:\Users\DELL\Pictures\文档图片\密钥不匹配.png)]
返回错误示例三
账户异常:最新版本的会显示出解密后哪个账户异常,账户异常请检查该账户是否被冻结、是否未设置密码、用户名、是否存在该账户、license数量是否充足等信息
{"msg":"该账号存在异常,单点登录失败userid:782","code":-1,"msgShowType":"none","status":false}
错误示例四:获取待办信息或者其他信息时请求到错误的人员上面
session导致用户信息错乱,请求时在请求头需要屏蔽所有的cookie,postman每一次请求都需要清理cookie,代码层面上也需要
返回错误示例五:
未获取到登录信息:请求头参数没有写全,请按照上述请求参数字段处理
{"err":"未获取到登录信息"}
四、jar包冲突导致的问题
4.1 北森jar冲突
查看stderr.log可发现以下报错(签名没有认证)或者其他报错(jar冲突)
Caused by: java.util.jar.JarException: file:/weaver/ecology/WEB-INF/lib/Beisen.OIDC.SDK.1.8.jar has unsigned entries - com/beisen/crypto/Crypto.class
如果发现了上述文件的报错,北森那边暂时只能提供源码解决依赖冲突,暂时没有其他解决方案
如果ecology/WEB-INF/lib路径下存在Beisen.OIDC.SDK.1.8.jar,可以屏蔽掉并重启测试token是否正常
如果没有上述报错,lib下存在Beisen.OIDC.SDK.1.8.jar也会发生冲突,目前北森提供的只有源码,这个地方应该北森来解决而不是我们来解决
4.2 bcprov问题
查看stderr.log寻找以下报错信息,签名没有认证
Caused by: java.util.jar.JarException: file:/weaver/ecology/WEB-INF/lib/bcprov-jdk15on-1.68.jar has unsigned entries - org/bouncycastle/LICENSE.class
替换为1.68最新版本(需重启ecology)
下载链接:
(下载jar)
五、常见疑问解答
5.1 公钥私钥的有效时间
只要不被更新就是永久有效
5.2 applytoken接口一直解密失败
先使用postman进行测试,如果第二步一直失败,请按照四、jar包冲突的解决方案进行解决
5.3 regist接口调用后之前的解密失败
adDoc?tokenKey=cloudstore/2022/09/C/d9c6c8dd-2345-4c5e-8ad9-b5716be89a87.wfile&fileName=jarfile.zip&appId=af09c25938714c26b9736f535ca20fc9&access_token=592acc7aa11012e8fc215a37d4f7473115f682eec0099006d6aad6f3c7a910ed762513a49008e7a90add5aa62fa27229736c8e229c99da05))
五、常见疑问解答
5.1 公钥私钥的有效时间
只要不被更新就是永久有效
5.2 applytoken接口一直解密失败
先使用postman进行测试,如果第二步一直失败,请按照四、jar包冲突的解决方案进行解决
5.3 regist接口调用后之前的解密失败
regist接口不需要注册多次,如果有不同的应用去请求,请放入多个appid隔离,对于分布式异构系统需要自行解决并发状态下密钥被更新的问题或者更新到ecology最新版本
Ecology异构系统认证流程时序图相关推荐
- Android 4.0系统打电话和接电话系统流程时序图详解
鄙人初学Android系统源码还不到半载,之前一段时间由于工作原因,稍微研究了一下Android4.0系统打电话和接电话的大致流程.现将自己的研究结果以时序图奉上,由于经验有限,若有错误还请见谅. 打 ...
- 售后服务工单系统用例图时序图
工单用例图 1,工单系统整体用例图 2,工单信息用例图 3,派单信息用例图 4,过程信息用例图 ...
- 详解支付流程时序图,再也不怕问题支付的问题了
- SSO流程(一图流)
一图轻松理解sso流程 sso认证流程时序图 总结 sso认证流程时序图 总结 上图描述的流程主要包括两个过程:用户首次登陆A.abc.com,以及登陆过A.abc.com后再登陆B.abc.com的 ...
- UML之顺序图(时序图)
UML学习之顺序图(时序图绘制) 1. 什么是时序图 时序图(Sequence Diagram),又名顺序图.序列图.循序图,是一种UML交互图.它通过描述对象之间发送消息的时间顺序显示多个对象之间的 ...
- UML时序图(Sequence Diagram)
什么是时序图 时序图(Sequence Diagram),又名序列图.循序图,是一种UML交互图.它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作. 让我们来看一看visio2016对时 ...
- UML时序图(Sequence Diagram)学习笔记
UML时序图(Sequence Diagram)学习笔记 原创 SuperMan-zhang 最后发布于2018-07-04 14:37:25 阅读数 94844 收藏 发布于2018-07-04 1 ...
- 【工具】-10 UML时序图(Sequence Diagram)学习笔记
为什么要绘制时序图? 我们编码的时候,知道有的用例的业务逻辑按照比较确定的时间先后顺序进行展开.这时候,我们就需要知道我们设计的系统中的不同类之间传递消息(可以认为是不同对象函数间的调用)要按照怎么样 ...
- UML时序图(序列图)
什么是时序图 时序图(Sequence Diagram),又名序列图.循序图,是一种UML交互图.它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作. 让我们来看一看visio2016对时 ...
最新文章
- 干货 |“NLP”与“语言学家”的那些事儿
- hihocoder #1333 : 平衡树·Splay2
- 分析linux系统的运行性能,Linux系统如何分析CPU的性能瓶颈
- [机器学习笔记] Note4--逻辑回归
- MySQL的未来在哪?
- ICCV 2019 | ActivityNet 挑战赛冠军方案—时序动作提名,边界匹配网络详解
- java连本地mysql注意事项_java数据库连接及注意事项
- PostreSQL崩溃试验全记录
- jmeter学习指南之Beanshell Sampler 常用方法
- ERROR: role company3 does not exist
- leetcode刷题日记-846. 一手顺子
- 中rsa非对称加密_HTTP的数据传输中,对称加密和非对称加密的区别是什么?
- 深度学习CNN算法原理
- 现代通信技术之SDH技术
- 《那些年啊,那些事——一个程序员的奋斗史》二
- Asterisk G729编码支持
- 74HC573锁存器的原理和使用
- python游戏制作rpg_python实现的简单RPG游戏流程实例
- 一年工作经验的java工程师从工作初到今天的所有收藏的…
- 一台计算机地址线32根,若有一台计算机,它的地址线有32根,则它的寻址空间是...
热门文章
- vue+ElementUI el-table表格单元格编辑增加键盘事件功能(向上、向下、回车键盘事件)
- C# 解析 sln 文件
- 《惢客创业日记》2019.09.09(周一)姚明的鼓励方式
- 自媒体运营抖音快手发什么作品涨粉快
- vue 用echarts画图表
- Java8学习--Map的compute方法
- threshold计算机英语,计算机专业英语
- 瞎写 - 如何“免费”在codeforge下载代码
- 查看was发布的应用程序的端口
- vue + echart +map中国地图,省市地图,区县地图