使用 SQL 服务器的 CONTEXT_INFO 进行经典 ASP 登录跟踪

Using SQL Server's CONTEXT_INFO for Classic ASP Login Tracking

我正在将经典 ASP 网站迁移到 ASP.NET MVC。作为迁移的一部分,我们已将数据库从 MS Access 移动到 SQL 服务器,并在 SQL 端设置了基本的触发器级审计日志记录,以备不时之需。

我想做的是跟踪经典 ASP 站点的当前登录用户,以进行触发级审核。

对于 MVC 端的事情,我将 SQL 的 SET CONTEXT_INFO (ref) 与 Entity Framework 和 "one data context per request" 规则结合使用,这允许我将上下文信息设置为当前登录的 MVC 用户 ID。一切都很好。

我想与经典 ASP 网站一样,但不确定如何。有没有一种方法可以像在 MVC 中那样捕获 "per request" 来设置 CONTEXT_INFO?我对 Classic ASP 管道的工作方式不太熟悉,不知道是否可以完成,或者数据库连接(作为包含文件和 ADODB 连接中的连接字符串实现)是否会保留在应用程序池,这意味着我没有办法做到这一点。有谁知道这是否可能?

这是一些事实。

  • CONTEXT_INFO 存储在会话/批处理范围而不是连接中。

来自 Using Session Context Information

Session context information enables applications to set binary values of up to 128 bytes that can be referenced in multiple batches, stored procedures, triggers, or user-defined functions operating on the same session.

  • 当你从池中获取连接时,ADO(有一个体面的,最好是官方的数据提供者,比如 SQLOLEDB,当然 SQLNCLI)执行 sp_reset_connection 表示正在重用连接。

  • 从 SQL Server 2005 * 开始,sp_reset_connection 重置 CONTEXT_INFO

来自System Stored Procedures (Transact-SQL)

The sp_reset_connection stored procedure is used by SQL Server to support remote stored procedure calls in a transaction. This stored procedure also causes Audit Login and Audit Logout events to fire when a connection is reused from a connection pool.

总之,在开放会话期间使用 CONTEXT_INFO 是安全的。

因此,只要您在请求期间坚持使用相同的连接对象引用 (adoCon),下面的代码就符合 one data context per request 规则。

<%
Dim adoCon ' global scope variable
Set adoCon = Server.CreateObject("ADODB.Connection")

adoCon.ConnectionString = "Provider=SQLNCLI10;Data Source=..."
adoCon.Open 'connection taken from the pool, a session "possibly recycled" started

'CONTEXT_INFO() is definitely NULL right now

adoCon.Execute "SET CONTEXT_INFO 0x01"

'all database operations through the adoCon ...

adoCon.Close 'connection closed, session released
%>