2017-05-09 41 views
1

我有以下代码:SQLCLR模拟保持使用该服务的身份

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\42.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组件的declation如下:

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 Server,并希望该用户执行文件访问。

我在这里错过了什么?

+0

这看起来不错。你可以在'If SqlContext.WindowsIdentity IsNot Nothing Then'条件中调试并设置一个断点,否则添加一行会在那里做一些清楚地表明该分支已经进入的行。另外,为什么你认为安全环境仍然是“NT SERVICE \ MSSQLSERVER”而不是你的Windows登录? –

+0

我100%确定它进入内部IF,我通过在那里设置一个固定的返回值来证明它。我使用System Internals ProcMon来查看哪个用户正在访问该文件夹。 –

+0

嗯。您可能想通过只允许对Windows登录进行读取访问,然后将'Exists()'更改为'string _Test = ReadAllText()'或类似的东西来进行测试。 –

回答

0

您的代码看起来是正确的。您可以通过只允许您的Windows登录的读取权限进行测试,然后将Exists()更改为string _Test = ReadAllText()或类似的内容。

你最初看到的是过程的主要身份。冒充另一个帐户不是替代原始安全上下文,它仅仅是一个新的SID(安全ID)来运行该过程。实际上,冒充OS帐户不会改变注册表中的“活动”用户(即HKEY_CURRENT_USER),也不会重置环境变量(即PATH,TEMP等);这些操作发生在完整登录时。

在SQL Server中,当通过EXECUTE AS模拟时,您可以通过ORIGINAL_LOGIN()内置函数看到Session的主要身份。

0

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

按设计工作!