QSecurity 是 QPlugins 的安全相关插件接口及其实现, qplugins_security.pas 定义了安全相关的接口,我们在插件中使用时,只需要引用这个接口文件就可以了。而服务的实现单元并不包含在免费开源的范围内,如果您不想自己实现,或者想参考实现,需要付费购买,价格为人民币 99.00 元。
无论是我的实现,还是您自己去实现这些接口,它的用法是一样的,所以这个入门教程适合兼容于qplugins_security 接口的所有实现。
一、查找 IQSecurityService 服务
查找 IQSecurityService 服务接口和查找普通的服务是一样的,有多种方式:
- 如果你不知道服务的路径,那么直接通过 PluginsManager 来查找 IQSecurityService 实例即可,当然这并不是效率最高的方式,因为 PluginsManager 会遍历查找所有注册的接口及服务,以便找到它。但它是最易用的一种方式,在 Delphi 中,可以:
123456varAService:IQSecurityService;beginAService:=PluginsManager as IQSecurityService;....end;
或者
12345678varAService:IQSecurityService;beginif Supports(PluginsManager ,IQSecurityService ,AService thenbegin....end;end;
或者:
12345678varAService:IQSecurityService;beginif PluginsManager.QueryInterface(IQSecurityService ,AService)=S_OK thenbegin....end;end;
当然,这几种方式本身没啥优劣之分,第一种要求服务必需已经注册才能使用,而后两种都会判定是否存在相应的接口。如果确认支持相应的服务,那就放心使用第一种方式,它在 Delphi 中最方便。 - 如果您知道服务的路径,按注册路径查找更快一些,我实现的服务注册路径为 /Services/Security,所以像下面这样子调用:
123456varAService:IQSecurityService;beginAService:=PluginsManager.ByPath('/Services/Security') as IQSecurityService;....end;
二、注册自己模块的权限
对于松散耦合的应用开发来说,你永远不知道啥时候增加啥模块,而增加模块就意味着可能增加新权限项目。QPlugins Security 模块将这一步交由插件自身,“自事自知”,通过启动时注册自己的权限,然后授权模块就可以为用户进行授权。
一个简单的例子(我们继续接上面的 AService)是安全管理服务注册自己的权限:
- 定义权限的ID,它是一个GUID编码,你自己模块随意定义就可以,不需要关心其它模块的定义,毕竟你用 Ctrl+Shift+G 生成的随机的 GUID 编码与其它人定义重复的可能性很低。这个 ID 是你程序中检查权限的基础,一般我们会为权限进行分组,象下面的示例中,定义的是一个分组ID,两个子项权限:
1234567const// 角色及权限管理分组IDSID_SECURITY_GROUP: TGuid = '{110CA18E-4B52-4D75-B3F3-9C99DC2B76FE}';// 查看其它用户账号及权限SID_SECURITY_VIEW: TGuid = '{B02A4134-3563-42A0-825E-C90BB5DD031E}'; //// 修改其它用户账号及权限等资料SID_SECURITY_EDIT: TGuid = '{800896A0-E733-48BB-8CB4-857EC83F6F89}'; - 在插件的 initialization 里,注册权限:
1234567891011121314varARights:IQSecurityRights;AService:IQSecurityService;beginwith PluginsManager as IQSecurityService dobegin//注册分组ARights:=IQSecurityRights(GetRootRight).AddGroup(SID_SECURITY_GROUP,'账号及权限管理', TQAccessRight.arDeny);//注册子权限ARights.AddRight(SID_SECURITY_VIEW, '查看存在的账号及角色信息', TQAccessRight.arDeny);ARights.AddRight(SID_SECURITY_EDIT, '管理账号、角色及其权限', TQAccessRight.arDeny);end;end;
注册完成后,内存中就有了相应的权限对象。
三、判断当前用户权限
在需要判断权限的地方,通过 IQSecurityService.CanAccess 即可,比如:
1 2 3 4 5 |
with PluginsManager as IQSecurityService do begin btnView.Visible:=CanAccess(SID_SECURITY_VIEW); btnEdit.Visible:=CanAccess(SID_SECURITY_EDIT); end; |
QSecurity 用户权限检验的规则说明如下:
- 用户如果未登录,则根据权限对象默认权限定义返回;如果默认权限不是明确的允许或拒绝,则继承自全局的默认权限。在我的实现中,它是拒绝。如果你确定某个权限默认开通,那你可以在上一步注册权限时,将默认权限设置为 arAllow 即可。
- 如果用户已经登录,则根据以下规则执行:
(1)在当前登录用户级别上,明确了允许还是拒绝,则返回明确的结果;如果没有,则检查有没有明确允许其父权限分组定义,如果仍没有,则遍历自己父角色执行同样的操作,以最终确定权限。
(2)如果当前用户多个父角色对同一对象的访问权限有冲突,那么按用户未登录时,检查权限的规则来处理。
四、注消权限注册
QSecurity 不支持权限的注销,也不需要插件释放相关的权限对象实例。
五、对插件修改当前用户权限的支持
出于安全原因,QSecurity 不允许其它插件去修改权限,相关的接口也不公开给其它插件使用。要修改当前用户的权限,通过 IQSecurityService 的 Config 接口来打开权限管理界面来修改。如果当前登录用户权限发生变动,还会发送 SNotify_RightsChanged 通知。
更多接口说明,请参考 qplugins_security 中相关接口函数的说明。
0 条评论
沙发空缺中,还不快抢~