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

时间:2020-01-15 15:11:48

标签: .net sql-server credentials impersonation sqlclr

我在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服务帐户的消息(我通过将服务设置为使用我的凭据来确认了这一点) ,然后CLR运行完美)

我的理解是,这样做的方法是在SQL Server中使用该帐户的详细信息创建一个Credential,因为documentation就是这样:

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

我可以做到,但是我似乎无法做到的是找到任何将凭证映射到程序集的方法。我该怎么办?

1 个答案:

答案 0 :(得分:1)

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

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

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

相关问题