2012-04-17 92 views
5

使用Delphi XE构建使用Datasnap的相对简单的数据库应用程序。将SQL登录凭证传递给Delphi Datasnap服务器的最有效方法?

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

(我试图使DataSnap服务器无国籍如果可能的话,所以承认,我将不得不在每次调用做到这一点。)

我在客户端使用ClientDatasets(CDS),所以我可以使用OnBeforeGetRecords将OwnerDataData 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?

非常感谢。

回答

3

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

+0

谢谢你,这似乎工作 - 显然现在你指出,但可能已经救了我几天。 – RichardS 2012-04-17 13:27:49

3

最安全的方式是传递用户安全令牌(加密的),然后在服务器端使用集成安全性,在线程中冒充主叫用户安全上下文。这样,任何用户/密码都不会通过线路发送。不幸的是,虽然MS/DCE RPC可以为每个调用(和DCOM,在RPC之上构建)做到这一点,但Datasnap无法(SPNEGO/GSSAPI/SSPI在Embarcadero看起来很复杂,他们喜欢简单的,不安全的协议)。否则,要非常小心地通过网络发送凭证的方式,除非正确受保护,否则它们可能很容易被嗅探。

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

相关问题