.net 如何将凭据映射到SQL Server中的SQLCLR程序集?

.net 如何将凭据映射到SQL Server中的SQLCLR程序集?,.net,sql-server,credentials,impersonation,sqlclr,.net,Sql Server,Credentials,Impersonation,Sqlclr,我在SQL Server中有一个CLR程序集,需要继承特定帐户的权限。CLR函数基本上只是获取一个网页,并以这种方式将其返回给SQL: [SqlFunction] [返回:SqlFacet(MaxSize=-1)] 公共静态SqlChars Get(SqlChars H,SqlChars url) { var client=new WebClient(); client.Credentials=CredentialCache.DefaultNetworkCredentials; AddHeade

我在SQL Server中有一个CLR程序集,需要继承特定帐户的权限。CLR函数基本上只是获取一个网页,并以这种方式将其返回给SQL:

[SqlFunction]
[返回:SqlFacet(MaxSize=-1)]
公共静态SqlChars Get(SqlChars H,SqlChars url)
{
var client=new WebClient();
client.Credentials=CredentialCache.DefaultNetworkCredentials;
AddHeader(H,客户端);
返回新的SqlChars(
client.DownloadString(
Uri.EscapeUriString(url.ToSqlString().Value)
).ToCharArray());
}
我希望它能够通过NTLM使用特定的帐户详细信息进行身份验证。这在SQL之外的C#程序中工作正常,但作为CLR函数,它只返回401条未经授权的消息,这是因为
DefaultNetworkCredentials
是SQL Server服务帐户的凭据(我通过将服务设置为使用我的凭据来确认这一点,然后CLR工作正常)

我的理解是,这样做的方法是在SQL Server中创建一个包含该帐户详细信息的帐户,因为

凭据提供了一种允许SQL Server身份验证用户在SQL Server之外拥有身份的方法。这主要用于在具有外部访问权限集的程序集中执行代码


我可以这样做,但我似乎无法找到任何方法将该凭证映射到程序集。我如何做到这一点呢?

我不确定SQL Server中的凭据是否真的是这样工作的(在该文档页面中描述的方式)。但是,即使它们可以通过SQLCLR模块用于外部操作,也不能通过向程序集分配任何内容来实现。SQL Server中的凭据映射到SQL Server登录。因此,您可以将凭证映射到一个或多个SQL Server登录,这些登录将执行基于SQLCLR的模块

而且,如果需要外部操作来使用默认安全上下文(SQL Server服务帐户)以外的安全上下文,则需要激活。这样做将假定正在SQL Server中执行基于SQLCLR的模块的Windows帐户的安全上下文。SQL Server登录不是Windows帐户,这就是为什么它们通常无法在.NET代码中进行模拟。也许通过将T-SQL凭证映射到SQL Server登录就可以了(我已经测试过了,但它不起作用;文档非常不正确;我将在GitHub上提交更正)。请记住和对象是一次性的,因此您需要使用(…){}构造将它们包装在
中,或者至少调用
try/catch/finally
try/finally
块的
finally
部分中的
Dispose()
方法。如果您使用的是Windows Auth登录,那么您可以进行此模拟,但它将模拟正在执行模块的任何登录,我假设这些登录可能是不同的帐户(即不一定是您的帐户),因此它们都需要访问外部资源


另一种选择是通过
newnetworkcredential()
直接在.NET代码中提供凭据。这样做不仅适用于SQL Server登录,还允许一个单独的帐户作为连接(您当然可以根据某些条件从列表中查找凭据以使用不同的凭据,但这至少允许通过单个帐户访问远程资源).

我不确定该声明中的文档是否正确。这似乎不会出现在任何其他与凭证相关的页面上。无论哪种方式,凭据都映射到SQL Server登录,而不是映射到程序集。而且,当您说“继承特定帐户的权限”时,您是否特别指用于外部操作(如文件系统、网络、注册表等)的Windows帐户?您能否更新问题以明确说明您试图执行的操作需要其他帐户的权限?谢谢。@SolomonRutzky更新解释-我想让它对特定的帐户详细信息进行NTLM验证。默认情况下,它将获取SQL Server服务帐户的详细信息。我已经用我的测试结果更新了我的答案。文件似乎有误,事实上不能以这种方式使用凭证。但是,我注意到有两种选择;这是一个非常全面的答案,我感谢测试工作。实际上,模拟可能会起作用,只有运行模拟的人才能访问该资源。我的目标是避免使用
new NetworkCredential()
,因为这意味着将凭据存储在某个地方,这总是让我感到不安。@DanScally不客气。我完全理解re:不想存储密码,特别是当密码需要纯文本时。可能还有其他方法来创建凭据,但我没有时间研究这个问题。但是,如果需要访问的用户都有Windows登录,并且这些登录都可以访问远程资源,那么可以使用模拟。。。祝你好运