如何将BI 工具与业务系统进行单点登录对接,实现用户权限通用

news2024/11/17 23:34:20

首先来看下两套系统的用户体系功能,左边是BI 工具,右边是业务系统,需要实现用户权限对接和打通:

单点登录体系及用户场景

• 场景1. 用户登录Wyn BI页面使用第三方业务系统账号
• 场景2. 用户使用第三方账号登录wyn BI以后需要获取用户信息(包括组织机构、用户上下文)
• 场景3. 用户在第三方页面调用wyn BI登录接口,获取wyn BI的登录token

Wyn BI安全提供程序接口




ISecurityProvider

• GenerateTokenAsync 生成用户token的核心方法(也是校验用户的核心方法)
• ValidateTokenAsync 校验用户token
• DisposeTokenAsync 注销用户token
• GetUserRolesAsync 获取用户权限
• GetUserOrganizationsAsync 获取用户组织机构
• GetUserDescriptorAsync 获取用户描述
• GetUserContextAsync 获取用户上下文

ISecurityProviderFactory

• CreateAsync 根据外部配置生成ISecurityProvider

IExternalUserContext

• GetValueAsync 获取用户上下文单值属性
• GetValuesAsync 获取用户上下文多值属性

IExternalUserDescriptor

• ExternalUserId 用户ID
• ExternalUserName 用户名称
• ExternalProvider

可以看到Wyn 提供的这几个接口,指的就是Wyn的用户权限控制模块。

前置配置

当对接Wyn权限体系使用 数据库或 API接口等方式时,往往希望能把关键接口地址 或者数据库配置信息能在前端显示修改, 这样能方便后续修改该配置而不用再修改代码。

关于配置项在前端往往显示为 key:value 形式, 表现为代码层面就是 ISecurityProviderFactory 工厂类的 SupportedSettings 属性,不难看出 SupportedSettings 类型便是 ConfigurationItem 的数组(可迭代)形式, 一般可把需要设置的setting key 通过硬编码的方式赋给 SupportedSettings 对象,来完成配置项对接。

ISecurityProviderFactory 该工厂类的 CreateAsync 方法便是安全提供程序的初始化入口, 在这里可以将外部配置信息通过 ConfigurationItem 对象来注入安全提供程序中, 以便后续查询用户信息使用。

场景1

由上图可以看出整个 Wyn 登录的接口入口函数就是 GenerateTokenAsync 函数来生成token,该函数的参数就是用户登录输入的用户名称、密码 (其他参数,场景3细讲), 最后产生结果就是一条用户token,这个token 可以理解为用户在wyn 中的当前用户信息索引。

从校验token信息之后的所有函数方法参数都是这条生成的token,所以易知后面的获取用户上下文、用户信息描述、用户权限、用户组织机构. 它们的基本思路都是 token 索引–>获取用户信息–>由用户信息构建要获取的对象(上下文、组织机构…)–> 返回获取对象。

这里构建token的方法没有规定,所以可以使用多种方法来生成token。

• 将用户信息通过编码加密方式直接存为token,后续获取用户信息直接反向解密即可拿到
• 将用户信息放到内存(redis)Map(dict)容器中,token即为对应键值对的key,后续通过 get(key) 的方式来获取用户信息
• 将第三方查询该用户信息的关键参数如 userId, userName 等参数编码为token, 后续通过解密为查询参数然后重新查询用户信息来获取

场景2

显而易见,IExternalUserContext 实际上就是用户信息的访问器, 指定的访问器方法分别是 GetValueAsync 和 GetValuesAsync . 这两个分别对应单值参数和多值参数, 通常情况下, 都会在 UserContext 对象中内置一个 User 对象来实现上述两个访问器的实现逻辑。当然在构建 UserContext 时,用户对象就要建立好, 这个就不赘述了。

IExternalUserDescriptor 类似, 但是因为它的访问属性是固定的,包含了用户id、用户名称等三个属性, 所以没必要再内置 user 对象, 直接构建 IExternalUserDescriptor 对应属性即可

场景3

获取token接口

// curl 调用
curl --location --request POST ‘http://localhost:51980/connect/token’
–header ‘User-Agent: Apifox/1.0.0 (https://www.apifox.cn)’
–data-urlencode ‘username=’
–data-urlencode ‘password=’
–data-urlencode ‘grant_type=<grant_type>’
–data-urlencode ‘client_id=<client_id>’
–data-urlencode ‘client_secret=<client_secret>’
–data-urlencode ‘tenant_path=<tenant_path>’
–data-urlencode ‘access-token-lifetime=’

//javascript fetch 代码

var myHeaders = new Headers();
myHeaders.append(“Content-type”, “application/x-www-form-urlencoded”);

var urlencoded = new URLSearchParams();
urlencoded.append(“username”, “”);
urlencoded.append(“password”, “”);
urlencoded.append(“grant_type”, “<grant_type>”);
urlencoded.append(“client_id”, “<client_id>”);
urlencoded.append(“client_secret”, “<client_secret>”);
urlencoded.append(“tenant_path”, “<tenant_path>”);
urlencoded.append(“access-token-lifetime”, “”);

var requestOptions = {
method: ‘POST’,
headers: myHeaders,
body: urlencoded,
redirect: ‘follow’
};

fetch(“http://localhost:51980/connect/token”, requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log(‘error’, error));

// axios 调用

var axios = require(‘axios’);
var qs = require(‘qs’);
var data = qs.stringify({
‘username’: ‘’,
‘password’: ‘’,
‘grant_type’: ‘<grant_type>’,
‘client_id’: ‘<client_id>’,
‘client_secret’: ‘<client_secret>’,
‘tenant_path’: ‘<tenant_path>’,
‘access-token-lifetime’: ‘’
});
var config = {
method: ‘post’,
url: ‘http://localhost:51980/connect/token’,
headers: {
“Content-type” : “application/x-www-form-urlencoded”
},
data : data
};

axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});

以上是 curl 和 javascript fetch/axios 调用获取token的方法, 接下来对参数内容加以说明:
• username 用户名 必填
• password 密码 必填
• grant_type 定值 “password” 必填
• client_id 客户端id 访问 客户端管理 可查询 或 查询 帮助文档 必填
• client_secret 客户端私钥 访问 客户端管理 可查询 或 查询 帮助文档 必填
• tenant_path 组织机构角色参数,形如 /A$1/B$2/C$3 表示 A部门1角色下的B部门2角色下的C部门3角色 选填
• access-token-lifetime token过期时间,单位秒 选填
这部分实际上只是第三方调用Wyn接口的场景,按场景1,场景2的内容开发完理应可以直接适应场景3的, 但需要有几个额外注意的点:

  1. tenant_path 这个参数表示的是组织机构角色参数, 也就是说这个场景下可能出现用户和 Wyn中的组织机构通过这个参数来绑定, 所以在生成 token的方法中也需要额外增加处理。tenant_path 参数并将其和用户信息进行绑定, 以便在后面的获取组织机构方法 GetUserOrganizationsAsync 中使用。
  2. 额外参数, 除了上面接口中的参数之外, 也可以添加其他自定义参数,以供生成token 方法中使用,具体值可以从customizedParam 中拿到。
    var externalParams = customizedParam as Dictionary<string, string>;
    string externalParam = externalParams[“key”]

代码建议
在 ISecurityProvider 方法中可能需要查询数据库、调用 API、调用SDK 的方式来获取第三方的用户信息, 这里建议加一层抽象的 service 功能层供 ISecurityProvider 调用使用, 在 service 层下层在添加连接数据库或者调用 API 的基础查询层, 这一层内容与业务代码完全无关, 只专注于实现后台基础的查询功能。

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

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

相关文章

栈与队列小结

一、理论基础1.队列是先进先出&#xff0c;栈是先进后出2.栈和队列是STL&#xff08;C标准库&#xff09;里面的两个数据结构。栈提供push和pop等等接口&#xff0c;所有元素必须符合先进后出规则&#xff0c;所以栈不提供走访功能&#xff0c;也不提供迭代器。3.栈是以底层容器…

求职陷阱:Lazarus组织以日本瑞穗銀行等招聘信息为诱饵的攻击活动分析

概述 Lazarus组织是疑似具有东北亚背景的APT组织&#xff0c;奇安信威胁情报中心内部追踪编号为APT-Q-1&#xff0c;因2014年攻击索尼影业开始受到广泛关注&#xff0c;其攻击活动最早可追溯到2007年。该组织早期主要针对其他国家政府机构&#xff0c;以窃取敏感情报为目的&am…

Java查漏补缺(15)java.io.File类的使用、IO流原理及流的分类、节点流、处理流、其他流的使用、apache-common包的使用

Java查漏补缺&#xff08;15&#xff09;java.io.File类的使用、IO流原理及流的分类、节点流、处理流、其他流的使用、apache-common包的使用本章专题与脉络1. java.io.File类的使用1.1 概述1.2 构造器1.3 常用方法1、获取文件和目录基本信息2、列出目录的下一级3、File类的重命…

CLion Remote Debug CrossCompile

CLion远程Docker调试ROS(交叉编译)的设置步骤 准备一个好用的docker&#xff0c;运行起来&#xff08;Docker Image一定可以跑cuda和图形界面的&#xff0c;否则启动不了CLion&#xff0c;可以不用浪费时间看本教程了&#xff09; 在docker镜像中配置好ssh和rsync&#xff0c;…

数据可视化第二版-03部分-06章-比较与排序

文章目录数据可视化第二版-03部分-06章-比较与排序总结可视化视角-比较与排序代码实现创建虚拟环境1. python版本管理2.切换到指定版本后安装虚拟环境切换路径到文件当前路径柱形图环形柱状图子弹图哑铃图雷达图词云图教材截图数据可视化第二版-03部分-06章-比较与排序 总结 …

18- TensorFlow模型中Keras进阶 (TensorFlow系列) (深度学习)

知识要点 导入数据: (x_train, y_train), (x_test, y_test) mnist.load_data()标准化处理: x_train_scaled scaler.fit_transform(x_train) # scaler StandardScaler()one-hot编码: y_train tf.keras.utils.to_categorical(y_train, 10) 定义神经网络: model t…

《数据库系统概论》学习笔记——第四章 数据库安全

教材为数据库系统概论第五版&#xff08;王珊&#xff09; 这一章简单记一下那几条sql的用法和两种存取控制和审计&#xff08;今年期末考了&#xff09;吧&#xff0c;不知道有啥好考的 数据库安全性 问题的提出 数据库的一大特点是数据可以共享数据共享必然带来数据库的安全…

算法练习(八)计数质数(素数)

1、问题描述&#xff1a; 给定整数 n &#xff0c;返回 所有小于非负整数 n 的质数的数量 。 2、示例如下&#xff1a; 3、代码如下&#xff1a; 第一种&#xff1a;比较暴力的算法 class Solution {public int countPrimes(int n) {int count1;if(n<2) return 0;for(in…

【数据结构必会基础】关于树,你所必须知道的亿些概念

目录 1.什么是树 1.1浅显的理解树 1.2 数据结构中树的概念 2.树的各种结构概念 2.1 节点的度 2.2 根节点/叶节点/分支节点 2.3 父节点/子节点 2.4祖先节点/子孙节点 2.5兄弟节点 2.6树的度 2.7节点的层次 2.8森林 3. 如何用代码表示一棵树 3.1链式结构 3.1.1 树节…

01-mybatis-快速入门、代理、CRUD练习

文章目录MybatisMybatis入门案例1、创建User表&#xff0c;添加数据2、创建模块&#xff0c;搭建框架2.1 创建模块注意&#xff1a;完善项目目录2.2 导入坐标2.3 编写 MyBatis 核心配置文件2.4 编写sql映射文件2.5 编码3、解决SQL映射文件的警告提示Mapper代理开发1、定义同名接…

python下如何安装并使用matplotlib(画图模块)

在搜索命令中输入cmd&#xff0c;以管理员身份运行。 输入以下命令&#xff0c;先对pip安装工具进行升级 pip install --upgrade pip 升级完成 之后使用pip安装matplotlib pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple 也可以使用pycharm来安装matp…

《嵌入式应用开发》实验一、开发环境搭建与布局(上)

1. 搭建开发环境 去官网&#xff08;https://developer.android.google.cn/studio&#xff09;下载 Android Studio。 安装SDK&#xff08;默认Android 7.0即可&#xff09; 全局 gradle 镜像配置 在用户主目录下的 .gradle 文件夹下面新建文件 init.gradle&#xff0c;内容为…

弹性盒子布局

目录一、弹性盒子属性二、认识flex的坐标轴三、简单学习父级盒子属性三、属性说明3.1、flex-grow一、弹性盒子属性 说明&#xff1a; div的默认样式&#xff1a;display:block 块盒子 display:flex弹性盒子&#xff08;可以控制下级盒子的位置&#xff09; 当两种盒子单独出现…

springboot 虚拟线程demo

jd19支持虚拟线程&#xff0c;虚拟线程是轻量级的线程&#xff0c;它们不与操作系统线程绑定&#xff0c;而是由 JVM 来管理。它们适用于“每个请求一个线程”的编程风格&#xff0c;同时没有操作系统线程的限制。我们能够创建数以百万计的虚拟线程而不会影响吞吐。 做个 spri…

实验心理学笔记01:引论

原视频链接&#xff1a; https://www.bilibili.com/video/BV1Qt41137Kv 目录 一、实验心理学&#xff1a;定义、内容及简要历史回顾 二、实验心理学和普通心理学、认知心理学的区别 三、实验方法与非实验方法 四、实验范式 五、实验中的各种变量 六、The science of psy…

Java项目---博客系统

博客系统url : 链接 项目已上传gitee : 链接 前言 之前笔者已经使用Servlet结合MySQL实现了第一版的个人博客。在这一版的博客系统中&#xff0c;将进行以下功能的升级&#xff1a; 框架升级&#xff1a;SSM版本&#xff0c;即&#xff08;Spring SpringMVC MyBatis&…

@Import注解的原理

此注解是springboot自动注入的关键注解&#xff0c;所以拿出来单独分析一下。 启动类的run方法跟进去最终找到refresh方法&#xff1b; 这里直接看这个org.springframework.context.support.AbstractApplicationContext#refresh方法即可&#xff0c;它下面有一个方法 invoke…

Linux基础命令-fdisk管理磁盘分区表

文章目录 fdisk 命令介绍 命令格式 基本参数 1&#xff09;常用参数 2&#xff09;fdisk菜单操作说明 创建一个磁盘分区 1&#xff09;创建分区 2&#xff09;创建交换分区 参考实例 1&#xff09; 显示当前分区的信息 2&#xff09; 显示每个磁盘的分区信息 命令…

关于单目标约束优化问题的讲解及实现过程

一、前沿 优化问题一直是工程领域、路径规划领域等绕不开的话题,而真正的实际问题不是只是单目标优化问题,而是涉及到高维度且带多约束的问题,其中约束包含等式约束、不等式约束或者二者都有,这给优化研究提高了难度。 在中学的时候,应该都遇到过线性规划问题,类似于如…

LeetCode 热题 C++ 200. 岛屿数量 206. 反转链表 207. 课程表 208. 实现 Trie (前缀树)

LeetCode200 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你可以假设…