delphi - 如何在 Datasnap 服务器方法单元中获取经过身份验证的用户名和密码?

标签 delphi authentication datasnap

一旦您使用正确的参数名称(Delphi Datasnap Server User Authentication 中进行了说明),Datasnap 身份验证就非常简单。下一个问题是在使用 FireDAC 数据库连接时能够使用相同的凭据。答案似乎隐含在Most efficient way to pass SQL Login credentials to Delphi Datasnap servers?中。尽管“简单转发”并没有真正解释如何完成代码。此外,这些凭据应与用于登录 Datasnap 服务器的相同凭据进行身份验证。这将防止数据库级别的模拟。

到目前为止,我还没有发现任何方法可以从服务器方法单元内以编程方式获取当前的 Datasnap 用户凭据。例如,在 BeforeConnect 事件中。我正在处理的代码是使用 Delphi XE7 使用 session 生命周期构建的独立服务器。

以下是连接到 Datasnap 服务器并请求数据时发生的事件的描述:

让我进一步解释一下:

通过使用一些 ShowMessage 指令,我可以在连接并发出数据请求时跟踪 Datasnap 的流程。在“测试”下运行服务器允许我显示事件附带的各种参数的内容。设置完成后,运行连接到服务器并请求数据的客户端将产生以下结果:

客户端登录按钮

  • 提供凭据对话(这是我的代码,不属于 TSQLConnection 出错了。)
  • 已输入用户名和密码。
  • 参数放置在 TSQLConnection.Params [DSAuthenticationPassword、DSAuthenticationUser]
  • 设置 TSQLConnection.Connected := True
  • 服务器事件 OnUserAuthenticate

    此时,连接已建立,尽管其他任何事情都没有发生 发生在服务器上。最重要的是,ServerClass 都没有 ServerMethodsClass 也没有被实例化。没有地方 我可以看到它存储身份验证凭据。

客户端获取数据按钮

  • 客户端连续打开两个客户端数据集。
  • 服务器 DSServerClass1.创建。这显然意味着
    ServerTransport 识别请求有效并继续
    创建处理 session 所需的资源。
  • ServerMethodsUnit3.Create。埋藏在 DSServerClass 的某个地方 有一个 GetClass 调用返回类的名称 关联的 ServerMethodsClass。命名的类被实例化。自从 ServerMethodsClass 最终源自 TDataModule 也意味着属性(property)流动。
  • OnUserAuthorize(显然是第一个数据集)
  • OnUserAuthorize(显然是第二个数据集)

数据返回到客户端(此时数据库凭据被硬编码到 TFDConnection ConnectionDefinition 中,只是为了将其返回 工作。)

OnUserAuthorize 向 Sender 参数提供 nil 值;还提供了一个 TDSAuthorizeEventObject,它不包含任何我能够用来查找 ServerMethods 实例的引用,最后还有一个名为 Valid 的参数,它是一个用于授权用户的 bool 值。

请注意,TDSAuthorizeEventObject 包含对 TDSServerMethodUserEventObject 的引用,该引用确实包含用户名以及角色、授权角色和拒绝角色。然而,那又怎样呢?这让我回到了最初的问题:如何将其传达给 ServerMethodsUnit 中的代码?

最佳答案

过了一段时间,我在 Bob Swart 的白皮书中偶然发现了执行此操作的确切方法。有多种方法可让您在 Datasnap session 期间保留信息。这些属于 TDSSessionManager.GetThreadSession,分别是 GetData、PutData、RemoveData、HasData、GetObject、PutObject、RemoveObject 和 HasObject。这些方法实际上管理属于 session 一部分的两个字典。例如,在 UserAuthentication 事件中,您可以按如下方式存储用户名:

TDSSessionManager.GetThreadSession.PutData('entrykey', UserName);

稍后,在数据库连接的 OnBeforeConnect 事件中,您可以检索这些值以在连接中使用:

DBUserName := TDSessionManager.GetThreadSession.GetData('entrykey');

在实践中,我发现“对象”形式具有更大的值(value),但这两种形式都提供了一种强大的方法,可以在 session 的整个生命周期中保留您自己的数据,而无需诉诸外部媒体。

关于delphi - 如何在 Datasnap 服务器方法单元中获取经过身份验证的用户名和密码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28648275/

相关文章:

authentication - 使用 Azure 托管服务标识和应用服务身份验证的服务到服务身份验证?

java - 使用 Spring security 3 仅使用用户名对 REST 用户进行身份验证

delphi - IntraWeb/DataSnap?

delphi - Datasnap xe 与 Remobjects DataAbstract

Delphi FireDac (TFDConnection) 连接到 Sphinx 服务

delphi - 关于加入 TObjectlists

delphi - 如何在TWebBrowser中设置语言

windows - 如何让我的程序在 Windows 7 启动时以不同的权限运行?

windows - 搁置线程是最优的吗?

android - 如何在您的 Android 应用程序中使用谷歌帐户