从kbmMW v.4.40开始,引入了一个新的非常灵活的授权管理器。

它的目的是为开发人员提供为用户定义资源权限的功能,这是一个可选功能,将现有的授权事件驱动方案内置到kbmMW中,使授权开发任务更容易实现。

据说一张图片值1000字......让我们看看是不是这样:

上述图显示了一个典型的用户如何与应用服务器(绿色的东西)内的功能相互作用。 此外,它还显示了新的身份验证管理器如何添加到应用程序服务器,以及它如何在内部运行。

基于这张图,我还是要用1000多的文字来解释这是怎么回事。

首先:什么是你感兴趣的呢?

如果您计划或已经为一个或多个客户端提供本地集中功能,并且所提供的功能应取决于客户端的确切位置以及客户端的行为方式,那么您可能会对此感兴趣。

这是安全性的问题。 安全性通常作为对客户端中的信任方案实现,或者作为数据库中的强制功能实现。

对客户信任为基础的安全方案基本是一致的,因为没有安全性可言,不需要太多幻想,客户端软件(至少部分地)就可以轻易被一个不那么好的行为客户端替换,造成的结果也可想而知,系统由此变的不安全,数据被盗窃或者被破坏。客户端应用程序必须表现良好以确保您的数据不受错误影响这是作为开发者的责任,此外,系统还很难添加另一种客户端应用程序(例如移动应用程序),保证他安全地访问和操作数据库中的数据,添加的客户端需要实现与第一种客户端相同的安全层,这意味着代码需要重用,不要大量复制/粘贴相同的代码,最终可能导致出安全漏洞。

数据库强制安全性要好得多,因为实际上有一个活动的中间层负责决定客户端可以做什么而不用处理数据库中的数据。 但是,如果您执行的操作不仅仅是从数据库访问相当简单的数据结构,那么如果数据库实际上包含自己的编程语言,您将不得不求助于特定于数据库的编程语言,如TransactSQL,PL / SQL等,或者 您将把功能移动到客户端,在上面的段落中指出这是一个次优的解决方案。

更好的解决方案是使用Delphi或C ++作为编程语言,将所有开发人员/业务定义的代码(如报告生成,数据导出/导入,计算等)放在开发人员控制器应用程序服务器上。换句话说,做一个三层的解决方案:客户端,应用服务器,数据库服务器。 这为您提供了最高的灵活性,更轻松地支持其他客户端类型,同时仍然维护一个可以强制执行安全措施的层。

kbmMW总是有事件和功能来处理请求的授权,但开发人员有责任编写实际代码来执行繁琐任务。

现在,随着kbmMW v4.40发布,提供了一个名为TkbmMWAuthorizationManager新组件。

还有之后的安全保护功能,可以定义多种“模式”。 我们选择使用一个非常灵活的,基于下面三个定义:

  • Actors
  • Roles
  • Resources

一个Actor通常是同一个用户,具有一个登录名和口令,以及默认的角色(role)。 Actor也不一定为现实中的用户,它也可以由应用程序本身使用,例如允许应用程序在特殊情况下充当特定的Actor。

一个Actor可以有不同的“帽子”..基于系统中不同的角色(role)运行。

Resource是基本的东西,你作为开发商,希望把某种需要保护的东西命名。 例如,它可以是特定的kbmMW服务,或kbmMW服务中的特定功能,但由于开发人员100%负责选择资源的命名方案,开发人员可以想到的任何东西都可以成为资源(resource)。

基于这三个定义,开发人员就可以定义授权了。 授权指属于特定角色(role)的用户(actor)是否可以访问特定资源。

此外,授权可能仅在特定时间段内有效(例如上午9点至下午3点,或仅周三,或仅4月1日等),并且可能仅在请求来自特定物理客户端时才有效。 在kbmMW中,我们称之为约束的限制。授权可标记有零个或多个约束。

我们已经谈了很多关于actor。 但在现实世界中,我们拥有用户,这些用户需要进行身份验证并被识别为已定义的角色之一。 为此,我们在kbmMW的授权系统中有最终的子组件:登录。

一个登录是验证已知列表中的actor的用户名/密码。 如果用户名/密码通过验证,则会根据任何已定义的登录约束做进一步检查,登录约束定义了基于例如时间或客户端位置等可能不允许登录的特殊情况。

现在,我们为演示应用服务器增加安全功能。

如上图,拖放一个TkbmMWAuthorizationManager到Form上,然后设置kbmMWServer的属性AuthorizationManager指向刚拖放的组件。现在,kbmMWServer就知道在适当的时候去请求他的授权管理器为他处理授权了。

什么是适当的时候? 当未登录到系统的用户尝试访问任何内容时,或者当已登录的用户尝试访问服务标志表明需要授权运行的服务时。 这可以在通过服务向导创建kbmMW服务时定义,但也可以在之后定义。

让我们看一个演示的查询服务(Query Service),即从SQLite数据库向客户端返回数据的查询服务。

unit Unit2;    

interface    

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
kbmMWServer, kbmMWQueryService, Db, kbmMemTable, kbmMWCustomConnectionPool,
kbmMWCustomDataset, kbmMemCSVStreamFormat, kbmMWSecurity,
kbmMWBinaryStreamFormat, kbmMWStreamFormat, kbmMWResolvers, kbmMWSQLite,
kbmMWServiceUtils;
type
TTestQuery = class(TkbmMWQueryService)
kbmMWBinaryStreamFormat1: TkbmMWBinaryStreamFormat;
ClientSideQuery: TkbmMWSQLiteQuery;
ALL_EVENTS: TkbmMWSQLiteQuery;
SELECTED_EVENT: TkbmMWSQLiteQuery;
kbmMWSQLiteResolver1: TkbmMWSQLiteResolver;
SELECTED_SPECIES: TkbmMWSQLiteQuery;
ALL_SPECIES: TkbmMWSQLiteQuery;
private
{ Private declarations }
public
{ Public declarations }
class function GetFlags:TkbmMWServiceFlags; override;
end; var
TestQuery: TTestQuery; implementation uses Unit1; {$R *.DFM} class function TTestQuery.GetFlags:TkbmMWServiceFlags;
begin
Result:=[mwsfListed,mwsfRunRequireAuth];
end; end.

没有太多的代码,除GetFlags类函数返回一组服务标志。 通过确保mwsfRunRequireAuth包含在服务标志集中,从而告诉kbmMWServer只允许对此查询服务中的所有功能都要经过授权才可以调用。

现在,需要决定我们的授权方案应该如何定义了。

可以直接在应用服务器中定义Actor,也可以在请求授权时通过从外部数据源(例如在数据库中定义的用户)来动态定义。

角色通常直接在应用服务器中定义,资源和授权也是如此,但角色实际上也可以通过XML文件来保存及调入所有内容,从而实现在外部进行动态定义。

为简单起见,我们选择此应用程序服务器已知Gertrude和Franz作为actor,Administrator和User作为两个角色。并在MainForm的OnCreate事件中定义他们,当然也可以在其他地方定义,但必须遵循,在定义前不能执行授权给任何人。

procedure TForm1.FormCreate(Sender: TObject); 
var 
  sd:TkbmMWCustomServiceDefinition; 
begin 
     sd:=kbmMWServer1.RegisterServiceByName('KBMMW_QUERY',TTestQuery,false); 
       
kbmMWAuthorizationManager1.AddRole('Administrator',);       
kbmMWAuthorizationManager1.AddRole('User',); 

     kbmMWAuthorizationManager1.AddActor('Gertrude','GertrudesPassword','User');       
kbmMWAuthorizationManager1.AddActor('Franz','FranzPassword','Administrator'); 
end; 

加入两个角色(Role),两个演员(Actor)。每个演员(Actor)的定义有一个默认角色(Role)。 任何actor都可以通过除默认角色之外的其他角色请求访问。 如果允许actor通过该角色访问资源,则仅取决于我们需要很快定义的授权。

接下来,需要弄清楚我们的应用服务器哪些资源需要保护,虽然已经定义了TTestQuery服务上的功能需要授权,但这并不具体。

如果我们让kbmMW完全自动地处理授权,kbmMW定义要由包含所请求的服务名称,点和所请求的函数名称的字符串标识的资源,如:“KBMMW_QUERY.QUERY”。

在我们的示例中,通过RegisterServiceByName将查询服务注册为“KBMMW_QUERY”,客户端请求查询服务时将使用该标识,并且客户端可以使用查询服务支持的功能,即“QUERY”,“DEFINITIONS”,“EXECUTE”,“RESOLVE”,“INVENTORY”或“METADATA”这些功能。

这意味着当客户端打开查询时,至少会在服务上执行“QUERY”功能。

如果您使用自己的自定义服务,则可能在服务端定义了大量自定义函数,而这些函数将是你的客户端要使用的函数。

在默认授权模式下,构造的资源名称为“KBMMW_QUERY.QUERY”,“KBMMW_QUERY.DEFINITIONS”,“KBMMW_QUERY.EXECUTE”等。

资源通过授权管理器的方法AddResource定义,必须提供资源名称和可选的父资源引用。我们可以使用定义资源树的功能,以便在我们为用户定义授权时最大限度地减少代码量。

var
adminResources,userResources:TkbmMWAuthorizationResource; 
… 
adminResources:=kbmMWAuthorizationManager1.AddResource('AdminResources',nil);
userResources:=kbmMWAuthorizationManager1.AddResource('UserResources',adminResources);         
kbmMWAuthorizationManager1.AddResource('KBMMW_QUERY.QUERY',userResources);       
kbmMWAuthorizationManager1.AddResource('KBMMW_QUERY.DEFINITIONS',userResources);       
kbmMWAuthorizationManager1.AddResource('KBMMW_QUERY.EXECUTE',userResources);       
kbmMWAuthorizationManager1.AddResource('KBMMW_QUERY.INVENTORY',userResources);       
kbmMWAuthorizationManager1.AddResource('KBMMW_QUERY.METADATA',userResources);       
kbmMWAuthorizationManager1.AddResource('KBMMW_QUERY.RESOLVE',adminResources); 

我们已经定义了两个虚拟资源。一个名为AdminResources,没有父资源,另一个名为UserResources,其AdminResources为父资源。 换句话说,UserResources是AdminResources的子集,因此允许访问AdminResources的actor/role也可以访问UserResources。

现在用下面的代码定义授权:

kbmMWAuthorizationManager1.Grant('','User','UserResources',[mwapExecute]);
kbmMWAuthorizationManager1.Grant('','Administrator','AdminResources',[mwapExecute]); 

第一个语句授予任何扮演'User'角色的actor并在'UserResources'组中请求资源的授权,具有mwapExecute(执行请求)的权限。

由于可以明确的指定actor名称,而不是空字符串,因此您可以根据需要为特定人员制作非常精确的授权。 但是,在正常情况下,仅仅授权角色资源就更清晰了。

除了Grant之外,您还可以使用与上面相同的语法,仅使用Deny方法拒绝授权。 但是,它应该很少需要,如果是这样,它可以表明您应该检查资源树和角色定义,看看它们是否可以以不同的方式排列,以更好地满足您的授权需求。

如果任何客户端尝试连接到应用程序服务器并从查询服务请求数据,则将始终拒绝访问它们。 为什么?我们还是很怀念登录客户端。

下图为登录流程:

最简单的方法是让kbmMW应用服务器完全自动处理的登录流程。 我们可以通过将Options属性设置为包含mwaoAutoLogin来实现。

接下来的事情就是让客户端提供相关的用户名和密码。

这有多种方法,其中之一是使用TkbmMWSimpleClient组件,通过他的实例提供用户名与密码,然后所有的TkbmMWClientQuery组件通过Client属性使用TkbmMWSimpleClient组件实例,从而取代TkbmMWClientQuery内部使用的Client实例。

如果客户端在多线程中使用TkbmMWClientQuery,更好的方法是将TkbmMWClientQuery.ClientAsTemplate设置为true,并确保查询动作发生前先通过SimpleClient执行一次请求(它可能是一个虚拟的“LOGON”服务器端功能)。 该函数不必执行任何操作,用它确保在查询开始之前触发kbmMW登录过程,从服务器取得登录标记。

本文只涉及了什么可以与授权管理器来完成授权的基本概念,还没有讨论如何在实际数据表上添加更细粒度的授权,如何在不使用后登录超时,如何保存和加载XML的完整授权设置,如何将约束添加到登录和授权,如何允许匿名/未知用户访问特定功能,如何基于外部资源(例如数据库)动态定义角色等。

但是这一切都支持用新的授权管理机制来实现,至少我是希望能够更好地了解你的需求。

kbmMW授权管理解析(The kbmMW Authorization manager explained)的更多相关文章

  1. KbmMW 认证管理器说明(转载)

    这是kbmmw 作者关于认证管理器的说明,我懒得翻译了,自己看吧. There are 5 parts of setting up an authorization manager: A) Defin ...

  2. 在Asp.net MVC中使用Authorization Manager (AzMan)进行Windows用户身份认证

    背景 创建需要通过Windows用户进行身份认证的Asp.net MVC应用 要点 在Asp.net MVC应用基于Windows用户进行身份认证的方法有很多,如MVC自带的Windows认证就经常被 ...

  3. .NET Core中的认证管理解析

    .NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...

  4. MySQL for OPS 01:简介 / 安装初始化 / 用户授权管理

    写在前面的话 取这个标题的目的很简单,MySQL 在中小型企业中一般都是由运维来维护的,除非数据很重要的公司可能会聘请 DBA. 但是运维一般存在由于所需要了解的东西很多很杂,导致学习过程中很多东西只 ...

  5. MySQL 用户与授权管理详解

    大纲 一.前言 二.创建用户并授权 三.GRANT语句的种类 四.撤权并删除用户 一.前言 做为Mysql数据库管理员管理用户账户,是一件很重要的事,指出哪个用户可以连接服务器,从哪里连接,连接后能做 ...

  6. 安装window下的redis,redis可视化管理工具(Redis Desktop Manager)安装,基础使用,实例化项目

    以下包括内容: 一.redis下载安装,启动 二.Redis可视化管理工具(Redis Desktop Manager)安装 三.实例化项目 一.redis下载安装,启动 1,redis官方下载地址: ...

  7. RDIFramework.NET V3.3 WinForm版角色授权管理新增角色对操作权限项、模块起止生效日期的设置

    在实际应用在我们可能会有这样的需求,某个操作权限项(按钮)或菜单在某个时间范围内可以让指定角色访问.此时通过我们的角色权限扩展设置就可以办到. 在我们框架V3.3 WinForm版全新增加了角色权限扩 ...

  8. RDIFramework.NET V3.3 Web版角色授权管理新增角色对操作权限项、模块起止生效日期的设置

    在实际应用在我们可能会有这样的需求,某个操作权限项(按钮)或菜单在某个时间范围内可以让指定角色访问.此时通过我们的角色权限扩展设置就可以办到. 在我们框架V3.3 Web版本全新增加了角色权限扩展设置 ...

  9. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->WinForm版本重构岗位授权管理界面更规范、高效与美观

    岗位(职位)管理模块主要是针对组织机构的岗位(职位)进行管理,包括:增加.修改.删除.移动.对岗位设置用户,设置岗位的权限等.岗位管理在企业应用中是一个普遍应用的模块,也属于其他业务应用的基础.合理的 ...

随机推荐

  1. c 语言连续输入字符型数据

    #include<stdio.h> #include<stdlib.h> void Input1(char* &str){ // /* 这种情况下想要逐个输入字符串数组 ...

  2. php文件包含漏洞(利用phpinfo)复现

     利用docker复现该漏洞,访问http://192.168.80.156:8080/phpinfo.php,可以看到页面出现phpinfo页面 再访问http://192.168.80.156:8 ...

  3. prometheus远程连接m3db实现存储

    如果是prometheus server配置文件添加如下: remote_read: - url: "http://m3coordinator.m3db.svc.cluster.local: ...

  4. 子类父类(虚函数下的 引用指针 对象)->看来没有子类指针这回事

    #include<iostream> using namespace std; class Father { public: Father() { cout << " ...

  5. IQueryable 与 IEnumberable 接口的区别

    IQueryable 与 IEnumberable 接口的区别是: IEnumberable<T> 泛型类在调用自己的 SKip 和 Take 等扩展方法之前数据就已经加载在本地内存里了, ...

  6. thinkphp 3.2 加载第三方库 第三方命名空间库

    tp 自动加载的介绍: http://document.thinkphp.cn/manual_3_2.html#autoload 第三方库不规范库 不适用命名空间的库 可以使用import函数导入,其 ...

  7. python两个字典合并,两个list合并

    1.两个字典:a={'a':1,'b':2,'c':3} b= {'aa':11,'bb':22,'cc':33} 合并1:dict(a,**b)  操作如下: 合并2:dict(a.items()+ ...

  8. Java Web(十二) JavaMail发送邮件

    发送邮件的原理 概叙 邮件服务器: 要在 Internet 上提供电子邮件功能,必须有专门的电子邮件服务器.例如现在 Internet 很多 提供邮件服务的厂商:sina.sohu.163 等等他们都 ...

  9. linux磁盘管理 文件挂载

    文件挂载的概念 根文件系统之外的其他文件要想能够被访问,都必须通过"关联"到根文件系统上的某个系统来实现,此关联操作即为"挂载",此目录即为"挂载点& ...

  10. Win10系列:JavaScript获取文件和文件夹列表

    在应用程序中有时可能需要获取用户库中的内容,以便执行相关的操作.如果要获取某个用户库中的内容,需要先获取到这个用户库,获得用户库可以通过Windows.Storage命名空间中的KnownFolder ...