5

使用 Delphi XE 使用 Datasnap 构建一个相对简单的数据库应用程序。

由于我的应用程序中的某些安全性是在数据库级别处理的,因此我需要将用户的 SQL 凭据从我的客户端应用程序传递到我的 Datasnap 服务器。

(如果可能,我正在尝试使 Datasnap 服务器无状态,因此请认识到我必须为每次调用都这样做。)

我在客户端使用 ClientDatasets (CDS),因此我可以使用 OnBeforeGetRecords 将 OwnerData OleVariant 中的数据从客户端上的 CDS 传递到服务器上相应的 TDataSetProvider。但这意味着每个数据模块上的每个 CDS 都必须有一个执行此操作的事件,这看起来很混乱且笨拙。我不禁感到必须有一种方法可以将消息传递到更高级别的服务器。

我真正想要的是在服务器端的 DSServerClass 级别是这样的:

Procedure TMyServerContainer.MyServerClassCreateInstance(DSCreateInstanceEventObject: TDSCreateInstanceEventObject); 
begin 
// Server detects request for data from client app 
fUsername := GetUsernameFromClientSomehow; 
fPassword := GetPasswordFromClientSomehow;

// create data modules and initialise
MyDataModule := TMyDataModule.Create(nil); 
MyDataModule.InitialiseWithSQLCredentials(fUsername, fPassword); 
DSCreateInstanceEventObject.ServerClassInstance := MyDataModule; 
End;

身份验证管理器组件可以在这里帮助我吗?还有其他想法吗?还是我坚持使用 OnBeforeGetRecords?

非常感谢。

4

2 回答 2

3

您可以使用 SQL 凭据作为用户名和密码来连接到 DataSnap 服务器。这些值可以在身份验证管理器中验证和/或简单地转发到底层 SQLConnection 组件以连接到 SQL 服务器。

于 2012-04-17T12:25:13.960 回答
3

最安全的方法是传递用户安全令牌(加密),然后在服务器端使用集成安全性,在线程中模拟调用用户安全上下文。这样就不会通过网络发送任何用户/密码。不幸的是,虽然 MS/DCE RPC 可以为每个调用(以及构建在 RPC 之上的 DCOM)执行此操作,但 Datasnap 不能(对于 Embarcadero 的人来说,SPNEGO/GSSAPI/SSPI 看起来很复杂,他们喜欢简单、不安全的协议)。否则,通过网络发送凭证的方式要非常小心,除非得到适当的保护,否则它们很容易被嗅探。

无论如何,我建议您只发送一次,如果您需要(并且以最受保护的方式),然后将它们保护在服务器端(使用受 Windows 保护的存储设施),然后发送回客户端句柄/会话令牌(绑定到原始 IP),用于后续调用,而不是每次都重新发送凭据。当用户注销或会话超时时,信息将被清除。

于 2012-04-17T13:02:53.843 回答