4

我正在尝试找出“正确”的方法来从我的 DataSnap 应用程序的服务器建立到我的数据库的连接。

数据库中的每个(大多数)表都有字段(其值通过插入和更新触发器设置),称为更新和创建(这是写入记录时的当前时间戳)和 update_by 和 created_by(应该)包含当前登录的用户。

我希望用户从客户端“登录”,以便这些字段反映已登录的用户(并且通过扩展,我将从数据库获取用户身份验证,而不仅仅是从服务器获取)。我可以从客户端处理服务器本身的身份验证,可以处理服务器上的 OnUserAuthenticate 和 OnUserAuthorize 事件。然后我试图将凭据传递给我的数据库,以便触发器可以正确设置上述字段。

那么处理这种情况的方法是什么?我想知道是否可以使用来自客户端的 DSAuthProxyUser 和 DSAuthProxyPassword,但我找不到太多(任何)文档来说明我将如何使用它。我是否为每个连接的用户建立一个新的连接?这对我来说似乎最合乎逻辑。我不会有很多并发用户。前 30 名。最有可能是 5-10 名。但是这样做的“正常”方式是什么?我不想(希望我不必)将用户名传递给我的每个插入/更新以设置表中的值。

我希望我已经清楚地解释了我的情况。

谢谢

4

2 回答 2

2

我还没有使用它,但在我看来,Firebird 2 中引入的RDB$SET_CONTEXT()RDB$GET_CONTEXT()是您所需要的。使用这些函数,您可以设置(和获取)特定于用户会话(命名空间USER_SESSION)或当前事务(命名空间USER_TRANSACTION)的附加信息。您还可以检索当前会话(命名空间SYSTEM)的其他系统信息,但这可能与您的情况无关。

您需要做的是调用RDB$SET_CONTEXT()OnUserAuthorize 事件中的方法,例如使用(作为查询):

SELECT RDB$SET_CONTEXT('USER_SESSION', 'actualuser', '<name of user') 
FROM RDB$DATABASE

'actualuser'是我们使用的上下文变量。在您的触发器中,您可以检索名称(假设 PSQL,带有声明的变量actualuser

actualuser = RDB$GET_CONTEXT('USER_SESSION', 'actualuser');

然后,您可以actualuser在触发器的其余部分中使用。只需确保您还考虑了未设置上下文变量的情况(例如,管理员直接更改数据库或类似的东西)。

于 2012-12-01T09:24:48.333 回答
1

Firebird 具有可在 SQL 中使用的 CURRENT_USER 关键字。

以下示例基于http://www.firebirdsql.org/refdocs/langrefupd15-current_user.html

create trigger bi_customers for customers before insert as
begin
  New.created_by  = CURRENT_USER;
end

要获得更新的用户名,只需声明一个更新前触发器,如

create trigger bi_customers for customers before update as
begin
  New.updated_by  = CURRENT_USER;
end

此解决方案需要数据库用户到外部用户的 1:1 映射。在最简单的实现中,这意味着 DataSnap 会话根据数据库对用户凭据进行身份验证。

但是,在您的描述中,这似乎是一个两步验证(首先针对 DataSnap 层,然后针对数据库)。我不确定如何在安全密码处理方面做到这一点,以及您是否计划仅针对第一个身份验证阶段 (DataSnap) 使用单独的用户/密码表,以及从 DataSnap 到数据库的用户登录映射作为某种“解耦” '。

于 2012-12-01T10:32:09.813 回答