统一身份认证是整个 IT 架构的最基本的组成部分,而账号则是实现统一身份认证的基础。做好账号的规划和设计直接决定着企业整个信息系统建设的便利与难易程度,决定着系统能否足够敏捷和快速赋能,也决定了在数字化转型中的投入和效率。用户账号是用户身份的一种表示,传统统一身份认证系统往往被作为外围系统来集成各个应用系统,而不是作为核心基础系统被其他应用系统来集成。所以传统统一身份认证系统的建设存在众多的问题,使设计实现复杂化、管理复杂化、集成复杂化。

每个企业可能同时会有多套系统在运行,但每个用户的账号在企业中仅有一套,可以适用于各个系统当中。因此,这就涉及到我们如何将一套账号应用到各个系统中,保证账号的权限体系。

常见方法:

1、(最简单但最深恶痛绝的)数据复制一份导入到每一套系统中。这样会造成维护工作量大,数据混乱,如果是多级企业,将会发生难以想象的灾难。

2、在身份集成中,自定义安全程序的开发,用一套用户身份验证程序,集成到各个系统中。

本文将从以下三点来介绍如何编写自定义安全提供程序,并在项目中配置引用。

编写自定义安全提供程序

编写一个自定义安全提供程序的步骤如下:

(1) 创建项目

使用Microsoft Visual Studio 2017(以下简称VS2017),创建一个新的项目,类型选为 Visual C# - .NET Standard - 类库(.NET Standard),输入项目名称,如:MySecurityProvider:

(2) 添加程序包依赖

自定义安全提供程序所实现的接口是由几个程序包定义的,为此需要添加对这几个程序包的依赖。方法如下:

首先将下面这两个文件下载保存到本地硬盘,比如C:\Temp\pkg 文件夹下:

grapecity.enterprise.identity.externalidentityprovider.1.0.2.nupkg

GrapeCity.Enterprise.Identity.SecurityProvider.1.0.3.nupkg

单击VS2017的“工具”菜单的“NuGet包管理器”>“程序包管理器设置”:

选中“程序包源”,再单击加号按钮:

单击【...】按钮,指定“源”的路径为nupkg文件所在的文件夹,如:C:\temp\pkg

单击“确定”按钮保存设置。

在右侧解决方案资源管理器窗格中,右键单击“依赖项”,点击“管理NuGet程序包”,再点击“浏览”,选中新添加的程序包源,将会列出两个需要依赖的程序包:

GrapeCity.Enterprise.Identity.ExternalIdentityProvider和GrapeCity.Enterprise.Identity.SecurityProvider,如下图:

逐个选中程序包,点击“安装”,即可添加本项目对这两个程序包的依赖。

(3) 实现接口

自定义安全提供程序需要实现两个接口:ISecurityProviderFactory和ISecurityProvider。

实现第一个接口的操作步骤:

添加一个新的类文件,如MySecurityProviderFactory.cs,以实现ISecurityProviderFactory接口。

public class MySecurityProviderFactory: ISecurityProviderFactory

该接口规定了两个属性和一个方法:

public string Description // 本安全提供程序的描述字串。
public IEnumerable<ConfigurationItem> SupportedSettings // 本安全提供程序支持的用户配置项。

这些用户配置项将出现在Wyn的管理画面中,允许系统管理员进行设置。典型的配置项是用户信息数据库的连接字串。通过提供这种配置项目,可以避免在安全提供程序中硬编码用户信息数据库连接字串的问题。

public Task CreateAsync(IEnumerable settings) // 本安全提供程序的实例创建方法。

这个方法的内容几乎是固定的,如:

public Task<ISecurityProvider> CreateAsync(IEnumerable<ConfigurationItem> settings)
{
return Task.FromResult<ISecurityProvider>(new MySecurityProvider(settings));
}

实现ISecurityProvider接口

这个ISecurityProvider接口是安全提供程序的核心,其规定的属性和方法如下:

成员类型 名称 说明
属性 ProviderName 返回本安全提供程序的名称。
方法 GenerateTokenAsync 验证用户名和密码,通过时生成Wyn的访问令牌。
方法 GetUserContextAsync 返回用户的上下文信息,一般是根据用户名,从数据库查询得到用户的所属部门和其他业务数据。
方法 GetUserDescriptorAsync 返回用户的说明信息,该信息将用于门户页面的当前登录用户显示。
方法 GetUserOrganizationsAsync 返回用户的所属组织结构信息。
方法 GetUserRolesAsync 返回用户的角色信息,多个角色以字符串数组的形式返回。
方法 ValidateTokenAsync 验证令牌的合法性。在业务系统集成中,使用Token直接访问系统时,此方法用于检查传入Token的正确性。

除了上表所列成员,还有IExternalUserDescriptor,IExternalUserContext等接口,这些接口只是规定了实体类的属性,使用自定义类实现这些接口即可。

下面的文件附件是一个自定义安全提供程序的示例代码。

MySecurityProvider.zip

此示例代码中的解决方案(.sln)可在Visual Studio 2017中直接打开。示例代码文件夹\bin\debug中也包含Build产物DLL,可直接配置为Wyn的安全提供程序。示例的用户信息是保存在SQL Server数据库中的,请将本文件包中的db\MyUsers.bak文件恢复为SQL Server数据库。

有关接口的详细说明,请参考下面的接口介绍。

接口介绍

ISecurityProviderFactory接口

定义

public interface ISecurityProviderFactory
{
string ProviderName { get; }
string Description { get; }
IEnumerable<ConfigurationItem> SupportedSettings { get; }
Task<ISecurityProvider> CreateAsync(IEnumerable<ConfigurationItem> settings);
}

接口说明

属性和方法 说明
ProviderName 安全提供程序的名称,不能为空,不能和其它的安全提供程序重名。
Description 安全提供程序的描述文本,可以为空。
SupportedSettings 该安全提供程序加载和运行时所必须的配置项。比如安全提供程序需要访问数据库,那么数据库连接字符串即为一个必须的配置项,必须由管理员在安全提供程序管理页面配置好,该安全提供程序才能正常工作。可以没有任何必须的配置项,返回一个空列表即可。
CreateAsync 创建一个安全提供程序的实例。参数settings即为管理员已经配置好的配置项列表,用户可以在这里把配置项列表通过构造函数传入构建的安全提供程序实例。

ISecurityProvider接口

定义

public interface ISecurityProvider
{
string ProviderName { get; }
Task DisposeTokenAsync(string token);
Task<string> GenerateTokenAsync(string username, string password, object customizedParam = null);
Task<IExternalUserContext> GetUserContextAsync(string token);
Task<IExternalUserDescriptor> GetUserDescriptorAsync(string token);
Task<string[]> GetUserOrganizationsAsync(string token);
Task<string[]> GetUserRolesAsync(string token);
Task<bool> ValidateTokenAsync(string token);
}

接口说明

属性和方法 说明
ProviderName 安全提供程序的名称,不能为空,不能和其它的安全提供程序重名。
DesposeTokenAsync 使给定的token失效。
GenerateTokenAsync 判断给定的用户名和密码是否有效,如果有效,返回一个唯一的token;否则返回null或空字符串。注:该token可以是任何形式,比如用户的id,或这个用户信息加密后的字符串,只要确保安全提供程序可以根据这个token正确地返回这个用户的相关信息即可。
GetUserContextAsync 使用给定的token获取用户的上下文信息。用户的上下文信息包含哪些内容可以是随意的。
GetUserDescriptor 使用给定的token获取用户的基本信息。基本信息包括用户的id,用户名和安全提供程序的名称,都不能为空。
GetUserOrganizationsAsync 使用给定的token获取用户所属的部门信息。(该接口暂时没有使用)。
GetUserRolesAsync 使用给定的token获取用户的角色信息。返回用户所属角色的名称,这些角色的名称需要跟admin portal中列出的角色名完全匹配,否则会被忽略。
ValidateTokenAsync 验证给定的token是否是该安全提出程序提供的一个合法有效的token。

IExternalUserDescriptor接口

定义

public interface IExternalUserDescriptor
{
string ExternalUserId { get; }
string ExternalUserName { get; }
string ExternalProvider { get; }
}

接口说明

参数 说明
ExternalUserId 用户的唯一标识符。
ExternalUserName 用户名。
ExternalProvider 用户的提供者,即为安全提供程序的名称。

IExternalUserContext接口

定义

public interface IExternalUserContext
{
IEnumerable<string> Keys { get; }
Task<string> GetValueAsync(string key);
Task<IEnumerable<string>> GetValuesAsync(string key);
}

接口说明

参数 说明
Keys 用户上下文信息所包含的项目。
GetValueAsync 对于给定的key,获取其对应的用户信息。
GetValuesAsync 对于给定的key,获取其对应的用户信息,适用于多值情况。

注意

  • 在每个接口的实现函数中,必须有try-catch异常处理,在catch的异常处理部分,不要用throw语句再次抛出异常,而应返回Task对象,例如:return Task.FromResult(null); 其中T为接口函数规定的某个类型。
  • 用户上下文的key不要用以下字符串:sub,name,auth_time,idp,userid,email。

配置自定义安全提供程序

(1) 文件部署

将编译得到的安全提供程序DLL文件,复制到Wyn安装目录下的SecurityProviders文件夹下,在Windows环境下,默认路径为:

C:\Program Files\Wyn\Server\SecurityProviders

提示

如果安全提供程序还依赖其他DLL,也请一并复制到同一目录。

(2)重启服务

(3) 添加用户安全提供程序

以管理员身份登录到系统的后台管理网站,单击“+添加用户提供程序”。

勾选自定义的安全提供程序后保存。

(4) 配置安全提供程序

选中刚添加的自定义安全提供程序,右边将会显示可配置的设定选项。具体有哪些选项是在安全提供程序的代码中确定的。按实际配置输入这些选项内容即可。

输入完毕,单击“保存”按钮。

(5) 重启服务

为使自定义安全提供程序的设置生效,需要进入任务管理器重启WynService服务。

此后,就可以在登录窗口输入业务系统的用户名和密码来登录Wyn门户了。

注意事项

在编写安全程序中,我们需要注意的几个方法

  1. MySecurityProvider.cs 文件中的 GenerateTokenAsync 方法,此方法用于第一次登录中,验证登录信息的方法。所以这一步需要完成的功能就是验证用户名密码,案例中所给的验证方式为从数据库中直接获取用户信息后判断登录。这里可以实现自定义的验证方式。只需要对此方法中的 Database.GetUserInfo 这个被调用的方法进行改造即可。

    【链接数据库进行验证】

public Task<string> GenerateTokenAsync(string username, string password, object customizedParam = null)
{
string rst = null;
try
{
var userInfo = Database.GetUserInfo(username, password);
var roles = userInfo.RoleNames.Split(',');
var tokenValues = new string[roles.Length + 1];
tokenValues[0] = userInfo.UserName;
roles.CopyTo(tokenValues, 1);
var token = string.Join(Constants.TokenDelimiter, tokenValues);
token = Convert.ToBase64String(Encoding.UTF8.GetBytes(token)); rst = token; Database.WriteLogS("GenerateTokenAsync token=", token);
return Task.FromResult(rst);
}
catch (Exception e)
{
Database.WriteLogS("GenerateTokenAsync", e.ToString());
return null;
} }

【自定义验证,这里可以使用api,可以使用加密字符串等各类操作】

public Task<string> GenerateTokenAsync(string username, string password, object customizedParam = null)
{
string rst = null;
try
{
if (customizedParam==null)
{
return null;
}
Dictionary<string, string> parameters = (Dictionary<string, string>)customizedParam;
var userInfo = RSAHelper.UserDecrypt(username, parameters["key"], keyFileName);
if (userInfo == null)
{
return null;
}
var roles = userInfo.RoleNames.Split(',');
var tokenValues = new string[roles.Length + 1];
tokenValues[0] = userInfo.UserName;
roles.CopyTo(tokenValues, 1);
var token = string.Join(Constants.TokenDelimiter, tokenValues);
token = Convert.ToBase64String(Encoding.UTF8.GetBytes(token)); rst = token; Database.WriteLogS("GenerateTokenAsync token=", token);
return Task.FromResult(rst);
}
catch (Exception e)
{
Database.WriteLogS("GenerateTokenAsync", e.ToString());
return null;
} }

上图方法中,我们使用了自定义参数 其中key为我们自定义的键值对内容

在使用时可以这样配置:(自定义参数部分必须以 key:value 配置)

  1. MySecurityProvider.cs 文件中的 GetUserContextAsync 方法,根据方法追踪,最终所调用的方法为 Database.cs中的GetUserInfoByName 方法,所以过程忽略,直接改造此方法即可。

    注意:这里所返回的用户信息,则直接会在wyn中登录后所用到,所以这里注意返回结果信息。

    (图例3)【根据用户名获取用户相关信息】

【自定义返回信息】

  1. 若在程序中引用了其他dll,则需要在放入安全自定义程序时,将对应的dll放置到指定文件夹中。

    路径为此(默认安装路径,若更改安装路径,则自行寻找)

    C:\Program Files\Wyn\Server\SecurityProviders

  2. 日志打印,需要设置路径,在C盘创建log文件夹,否则打印不到。

  1. 配置界面信息设置



在当前页面看到的链接字符被修改为 秘钥(Base64) 这个可以在程序中直接配置,可以在 MySecurityProviderFactory.cs 文件中直接配置 SupportedSettings 此方法内容即可。

获取时在:MySecurityProvider.cs 自定义获取即可。

  1. 设置门户网站

  2. 返回的组织,角色如何处理?

    返回信息中,若组织,角色在系统中没有,则无法正常访问,可以在后台管理中设置对应的组织,角色,并且给角色分配响应的权限。

    设置组织:

传递的组织内容为:"/A/B" 顶级组织信息为 "/"

角色配置:给对应的角色设置权限

  1. 进程调试 ctrl+alt+p,选择 显示用户所有进程,选中dotnet.exe 打中断点。点击附加。程序中选择断点。

接下来就是打包测试了,将程序配置好之后,就可以正常测试使用了。

登录API客户端管理

登录api代码示例

通过postman调用生成token ,生成对应的安全自定义程序。

请求参数中:client_id,client_secret 为 Client Management 中所生成内容. 具内容参考 登录API客户端管理 默认信息有:

client_id:integration

client_secret:eunGKas3Pqd6FMwx9eUpdS7xmz

后期可以自行设置修改。

请求截图:

②代码请求如下:

fetch("http://localhost:51980/connect/token", {
"method": "POST",
"headers": {
"Content-type": "application/x-www-form-urlencoded"
},
"body": "grant_type=password&username=admin&password=admin&client_id=integration&client_secret=eunGKas3Pqd6FMwx9eUpdS7xmz"
}).then(function(res){
res.json()
.then(function(data){
console.log(data)
});
})

至此,已经可以获取到token了,获取后可以直接登录访问。

http://localhost:51980/integration?token=生成的token

到这里已经全部实现用户身份集成自定义开发,大家如果想了解更多商业BI行业精选模板,可以访问:

https://www.grapecity.com.cn/solutions/wyn/demo

BI如何实现用户身份集成自定义安全程序开发的更多相关文章

  1. ASP.Net Mvc实现自定义User Identity用户身份识别系统(2)

    上一篇博文中已经实现了如何在页面上使用自定义的属性即上篇博文所示的@this.U,今天将进一步研究用户自定义User Identity; 实现思路: 通过研究微软自带identity的套路,我们可以发 ...

  2. ASP.Net Mvc实现自定义User Identity用户身份识别系统(1)

    目的 当我们新建asp.net mvc 项目时,我们在使用下图所示的代码是否有以下思考: 1,在this.User.Identity.Name,为什么可以使用this便可以选中Name属性: 2,若项 ...

  3. SharePoint 2010以其他用户身份登录的弹出代码

    在SharePoint 2010平台中,可以在当前用户登录系统的情况下使用其他用户身份登录,以达到在同一浏览器中切换用户身份的目的. 每个用户登录SharePoint系统之后都会在系统右上角将用户的名 ...

  4. asp.net用户身份验证时读不到用户信息的问题 您的登录尝试不成功。请重试。 Login控件

    原文:asp.net用户身份验证时读不到用户信息的问题 您的登录尝试不成功.请重试. Login控件 现象1.asp.net使用自定义sql server身份验证数据库,在A机器新增用户A,可以登录成 ...

  5. 构建具有用户身份认证的 React + Flux 应用程序

    原文:Build a React + Flux App with User Authentication 译者:nzbin 译者的话:这是一篇内容详实的 React + Flux 教程,文章主要介绍了 ...

  6. 构建具有用户身份认证的 Ionic 应用

    序言:本文主要介绍了使用 Ionic 和 Cordova 开发混合应用时如何添加用户身份认证.教程简易,对于 Ionic 入门学习有一定帮助.因为文章是去年发表,所以教程内关于 Okta 的一些使用步 ...

  7. IdentityServer4(9)- 使用OpenID Connect添加用户身份验证(implicit)

    本文为 OpenID Connect 简化模式(implicit) 已更新至.NET Core 2.2 在本快速入门中,我们希望通过 OpenID Connect 协议向我们的 IdentitySer ...

  8. webapp用户身份认证方案 JSON WEB TOKEN 实现

    webapp用户身份认证方案 JSON WEB TOKEN 实现Deme示例,Java版 本项目依赖于下面jar包: nimbus-jose-jwt-4.13.1.jar (一款开源的成熟的JSON ...

  9. [置顶] Web用户的身份验证及WebApi权限验证流程的设计和实现 (不是Token驗證!!!不是Token驗證!!!都是基於用户身份的票据信息驗證!!!)

     转发 http://blog.csdn.net/besley/article/details/8516894 不是Token驗證!!!不是Token驗證!!!都是基於用户身份的票据信息驗證!!! [ ...

随机推荐

  1. 你不会用node 操作mysql数据库吗?

    http://static.runoob.com/download/websites.sql这是实例 websites.sql文件1.安装node的mysql服务 npm install mysql ...

  2. ms08-067漏洞复现

    一.环境说明 kali linux 靶机是 XP (xp启动445) 二.nmap扫描主机存在的漏洞 root@kali:~# nmap --script smb-vuln* 192.168.244. ...

  3. RPA SAP财务内部对账机器人

    [简介] 本机器人用于使用SAP软件的集团公司间往来对账前台登录SAP账户和密码,需退出PC微信,输入法切换为英文半角状态. [详细流程] 1.清空Excel-VBA管理工具原始数据 2.输入对账时间 ...

  4. 监控pos收银机

    1.打开pos收银机snmp功能 控制面板-->程序和功能-->启用或关闭windows功能→简单网络管理协议(SNMP) 2.配置snmp服务 控制面板-->管理工具-->服 ...

  5. go语言学习笔记-初识Go语言

    Go语言是怎样诞生的? Go语言的创始人有三位,分别是图灵奖获得者.C语法联合发明人.Unix之父肯·汤普森(Ken Thompson).Plan 9操作系统领导者.UTF-8编码的最初设计者罗伯·派 ...

  6. 降低PDF质量

    如果PDF尺寸过大,则需要降低其质量以缩小尺寸.在Linux下一条命令即可实现,而且效果不错: gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFS ...

  7. Error:(4, 13) java: -source 1.5 中不支持默认方法 (请使用 -source 8 或更高版本以启用默认方法)

  8. 4-7 CS后台项目练习-1

    1. 关于此项目 此项目是一个自营性质电商类型的项目. 当前目标是设计后台管理相关功能. 2. 关于项目的开发流程 开发项目的标准流程应该有:需求分析.可行性分析.总体设计.详细设计等. 建议课后学习 ...

  9. jdbc 01: 连接mysql,并实现数据插入

    jdbc连接mysql,并实现数据插入 package com.examples.jdbc.o1_连接与插入; import java.sql.*; /* jdbc数据库连接六步 */ public ...

  10. 掌握CSS中的z-index

    前言 z-index是一个用于控制文档中图层顺序的属性.具有较高z-index值的元素将会出现在具有较低值的元素之上.就像页面上的x轴和y轴决定一个元素在水平和垂直方向上的位置一样,z-index控制 ...