模拟和 CLR 集成安全性

托管代码访问外部资源时,SQL Server 不会自动模拟在其下执行例程的当前执行上下文。EXTERNAL_ACCESS 和 UNSAFE 程序集中的代码可以显式模拟当前执行上下文。

进程内数据访问提供程序提供了一个应用程序编程接口 SqlContext.WindowsIdentity,该接口可用于检索与当前安全上下文有关的令牌。EXTERNAL_ACCESS 和 UNSAFE 程序集中的托管代码可使用此方法检索上下文并使用 .NET Framework WindowsIdentity.Impersonate 方法模拟该上下文。当用户代码显式模拟时,适用下列限制:

  • 托管代码处于模拟状态时,不允许进程内数据访问。代码可以撤消模拟,然后调用进程内数据访问。请注意,这需要存储原始 Impersonate 方法的返回值(WindowsImpersonationContext 对象)并对该 WindowsImpersonationContext 调用 Undo 方法。

    该限制意味着当出现进程内数据访问时,实际它将始终位于该会话当前安全上下文的上下文中。在托管代码内无法通过显式模拟对此进行修改。

  • 为异步执行托管代码(例如通过 UNSAFE 程序集创建线程并异步运行代码),从不允许进程内数据访问。无论是否存在模拟,结果都将为 True。

当代码在与 SQL Server 中的上下文不同的模拟上下文中运行时,无法执行进程内数据访问调用,该代码在进行进程内数据访问调用之前应撤消此模拟上下文。当从托管代码中进行进程内数据访问时,指向托管代码中的 Transact-SQL 项的原始执行上下文始终用于授权。

EXTERNAL_ACCESS 程序集和 UNSAFE 程序集都使用 SQL Server 服务帐户访问操作系统资源,除非它们如上所述自动模拟当前的安全上下文。因此,EXTERNAL_ACCESS 程序集的作者需要具有比 SAFE 程序集的作者更高的信任级别,该级别由 EXTERNAL ACCESS 登录级别权限指定。只有被信任可在 SQL Server 服务帐户下运行代码的登录名才应被授予 EXTERNAL ACCESS 权限。