SQLCLR 模拟继续使用服务标识

SQLCLR Impersonation keeps using the service identity

我有以下代码:

Public Shared Function MyTest() As SqlString

    Dim rc As String = Nothing
    Dim impersonatedUser As WindowsImpersonationContext = Nothing
    If SqlContext.IsAvailable Then
        If SqlContext.WindowsIdentity IsNot Nothing Then
            impersonatedUser = SqlContext.WindowsIdentity.Impersonate
        End If
    End If
    Try
        rc = System.IO.File.Exists("C:\Data Files\Test.txt").ToString
    Catch ex As Exception
        Return ex.Message
    Finally
        If impersonatedUser IsNot Nothing Then
            impersonatedUser.Undo()
        End If
    End Try

    Return rc
End Function

在SQL中程序集声明如下:

CREATE ASYMMETRIC KEY aKeyCLR FROM EXECUTABLE FILE = '$(BASE)CLR.dll'
CREATE LOGIN CLRLogin FROM ASYMMETRIC KEY aKeyCLR
GRANT UNSAFE ASSEMBLY TO CLRLogin

创建函数:

CREATE FUNCTION dbo.Test()
RETURNS NVARCHAR(4000)
AS
    EXTERNAL NAME myStuff.[CLR.FileFunctions].[MyTest]
GO

当我执行 SELECT Test() 时,文件访问仍然由帐户 "NT SERVICE\MSSQLSERVER" 完成。我使用 Windows 身份验证登录到 SQL 服务器,并希望该用户进行文件访问。

我在这里错过了什么?

通过在 CreateFile 事件上进一步单击 ProcMon,事件属性会显示模拟用户。

按设计工作!

您的代码似乎是正确的。您可以通过仅允许对您的 Windows 登录名进行读取访问,然后将 Exists() 更改为 string _Test = ReadAllText() 或类似内容来进行测试。

您最初看到的是进程的主要身份。冒充另一个帐户并不是替换原来的安全上下文,它只是一个新的 SID (Security ID) 以 运行 的过程作为。事实上,模拟 OS 帐户不会更改注册表中的 "active" 用户(即 HKEY_CURRENT_USER),也不会重置环境变量(即 PATHTEMP, 等等);这些操作发生在完全登录后。

在 SQL 服务器中,当通过 EXECUTE AS 进行模拟时,您可以通过 ORIGINAL_LOGIN() 内置函数查看 Session 的主要标识。