我在SQL Server中有一个CLR程序集,我需要继承一个特定帐户的权限。 CLR函数基本上只是抓取一个网页,然后以这种方式将其返回给SQL:
[SqlFunction]
[return: SqlFacet(MaxSize = -1)]
public static SqlChars Get(SqlChars H, SqlChars url)
{
var client = new WebClient();
client.Credentials = CredentialCache.DefaultNetworkCredentials;
AddHeader(H, client);
return new SqlChars(
client.DownloadString(
Uri.EscapeUriString(url.ToSqlString().Value)
).ToCharArray());
}
我希望它能够使用特定的帐户详细信息通过NTLM进行身份验证。在SQL外部的C#程序中,此方法运行良好,但作为CLR函数,它仅返回401未经授权的消息,这是因为DefaultNetworkCredentials
是SQL Server服务帐户的消息(我通过将服务设置为使用MY凭据来确认了这一点,并且然后CLR可以完美运行)
我的理解是,这样做的方法是使用该帐户的详细信息在SQL Server中创建一个Credential
,因为这就是Credential
的意思:
凭据提供了一种允许SQL Server身份验证用户在SQL Server外部拥有身份的方法。这主要用于在具有EXTERNAL_ACCESS权限集的程序集中执行代码。
我可以做到,但是我似乎无法做到的是找到任何将凭证映射到程序集的方法。我该怎么办?
我不确定SQL Server中的凭据是否确实能以这种方式工作(该文档页面中所述的方式)。但是,即使可以将它们用于通过SQLCLR模块进行外部操作,也不能通过向程序集分配任何内容来实现。 SQL Server中的凭据映射到SQL Server登录名。因此,您可以将凭据映射到一个或多个将执行基于SQLCLR的模块的SQL Server登录。
并且,如果您需要外部操作来使用默认上下文(SQL Server服务帐户)以外的其他安全上下文,则需要激活documentation。这样做将假定正在执行SQL Server中基于SQLCLR的模块的Windows帐户的安全上下文。 SQL Server登录名不是Windows帐户,这就是它们通常无法在.NET代码中进行模拟的原因。 也许可以通过将T-SQL凭据映射到SQL Server登录名来进行(我已经对此进行了测试,但它不起作用;文档非常不正确;我将在GitHub上对其进行更正) 。请记住,Impersonation within the .NET code和WindowsIdentity
对象是一次性的,因此您需要将它们包装在WindowsIdentity
构造中,或者至少在WindowsImpersonationContext
的WindowsImpersonationContext
部分中调用using(...){}
方法]或Dispose()
块。
另一种选择是简单地通过finally
直接在.NET代码中提供凭据。