所以,我有一个SQLCLR函数,我已经编写以获取文件系统信息,如果我在本地SQL服务器上获取信息,但是当我尝试通过UNC在远程计算机上获取文件信息时,它可以正常工作路径(\\ server \ c $ \ directory \)我得到权限被拒绝的问题。我认为这是双跳权限问题,但我无法弄清楚如何解决这个问题。这是代码的简化版本,只返回文件名...以降低复杂性和行。
using System;
using System.Collections;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.IO;
using System.Security.Principal;
using Microsoft.SqlServer.Server;
namespace CLRFunctions
{
public class SQLFileSystem
{
[SqlFunction(FillRowMethodName = "FillRow", TableDefinition = "FileName nvarchar(500)", DataAccess = DataAccessKind.Read)]
public static IEnumerable fnGetFiles(SqlString Path, SqlString FilePattern, SqlBoolean Recursive)
{
String[] files = null;
WindowsIdentity clientId = null;
WindowsImpersonationContext impersonatedUser = null;
clientId = SqlContext.WindowsIdentity;
try
{
try
{
impersonatedUser = clientId.Impersonate();
if (impersonatedUser != null)
{
files = Recursive ? Directory.GetFiles(Path.ToString(), FilePattern.ToString(), SearchOption.AllDirectories) : Directory.GetFiles(Path.ToString(), FilePattern.ToString(), SearchOption.TopDirectoryOnly);
}
}
catch (Exception ex)
{
files = null;
}
finally
{
if (impersonatedUser != null)
{
impersonatedUser.Undo();
}
}
}
catch
{
throw;
}
return files;
}
public static void FillRow(Object obj, out SqlString FileName)
{
String file = (String)obj;
FileInfo fi = new FileInfo(file);
FileName = fi.Name;
}
}
}
这是我得到的错误。
Msg 6522, Level 16, State 1, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "fnGetFiles":
System.UnauthorizedAccessException: Access to the path '\\server\c$\temp' is denied.
System.UnauthorizedAccessException:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption)
at System.IO.Directory.GetFiles(String path, String searchPattern, SearchOption searchOption)
at VanClinic.Libraries.SQLFileSystem.SQLFileSystem.fnGetFiles(SqlString Path, SqlString FilePattern, SqlBoolean Recursive)
答案 0 :(得分:1)
默认情况下,Impersonation仅允许凭据在本地系统上运行。要在本地系统之外应用这些凭据,您需要为您的帐户启用委派。以下定义取自:http://msdn.microsoft.com/en-us/library/system.security.principal.tokenimpersonationlevel.aspx
模拟:服务器进程可以模拟客户端 本地系统上的安全上下文。服务器无法模拟 远程系统上的客户端。
委派:服务器进程可以模拟客户端的安全性 远程系统上下文。
此设置可在Active Directory中配置,还需要先设置SPN。下面的文章详细介绍了实现这项工作所需的步骤(我相信需要免费注册):