【问题标题】:Using SQL CLR to Call a Web Service使用 SQL CLR 调用 Web 服务
【发布时间】:2018-01-09 20:56:48
【问题描述】:

我按照这些人的演练进行了介绍,我在其他 Stack Overflow 帖子中看到了这些内容:https://code.msdn.microsoft.com/Calling-WCF-Service-from-a-8071ceaa

我在运行存储过程时遇到错误,该存储过程调用了类库,该类库具有应该调用 Web 服务的 Web 服务引用:

未找到设置属性 xxxx

我认为从我可以从这条模糊的消息中收集到的是,在配置中没有找到端点,以便 Web 服务客户端调用它。

不幸的是,撰写上述博客文章的人对此一无所知,并且在此特定消息上搜索了几个小时却一无所获。

【问题讨论】:

  • 您是否确认 .config 文件中包含该设置?您是否将编译后的 dll 移动到某处而不是复制其 .config 文件?
  • 感谢你们的快速回复,只是为了澄清一下,我使用的是 Visual Studio 2013、SQL Server 2014。我确实验证了配置文件中有设置,当我移动编译的 dll到托管 SQL Server 的服务器,我也移动了配置。 @Solomon,我没有遵循该帖子的指示来打开可信赖的功能,并找到了一些 MSDN 文档,介绍了如何按照您的建议执行操作并执行这些操作以尽可能保持安全性。看起来我可能只需要使用 HttpWebRequest 就可以了,因为我今天花了一整天的时间来尝试使用服务客户端使其工作。
  • 我所说的使用服务客户端的意思是,我创建了一个调用 web 服务的类库,将服务引用添加为高级选项下的 web 引用,而不是传统的服务引用,并且我的 WCF 服务运行良好,在该项目中对其进行了测试以确保安全。然后我做了第二步,用存储过程创建了一个数据库项目来调用前面列出的dll库中的静态函数,用ns.exe创建了非对称密钥,并对库和数据库项目进行了签名。使用 sql 命令编译它们,将它们移动到 SQL 服务器
  • 然后在 SQL Server 中进行了非对称密钥处理,正如@Solomon 提到的那样,尽可能保证它的安全,但仍然会遇到前面提到的找不到设置的问题。我想这是 CLR 过程调用 dll 库时返回的异常消息。无论如何,如果有人对可能是什么问题有任何想法,我感谢您的反馈。

标签: c# sql-server web-services wcf sqlclr


【解决方案1】:

了解您使用的 SQL Server 版本会有所帮助。但无论如何,如果您依赖ServiceModel 库(或您需要手动加载到 SQLServer 中的任何其他 .NET Framework 库),那么这将不起作用。您可以在 SQLCLR 中进行 Web 服务调用,但只能使用 Supported .NET Framework Libraries 列表中的库。

为了做这些事情,我 usually recommend 使用普通的 'ol HttpWebRequest / HttpWebResponse 类并手动处理 XML 的创建和解析(嗯,使用可用的 .NET 类)。它不会自动为您提供强类型对象,但可以保证它适用于所有版本的 SQL Server。

此外,该帖子中启用TRUSTWORTHY 的建议是不好的建议。相反,您应该签署程序集,然后从 DLL 在master 中创建一个非对称密钥,然后从该非对称密钥创建一个登录名,最后授予该登录名的EXTERNAL ACCESS ASSEMBLY 权限。可以通过多种方式完成此操作,具体取决于您使用的 SQL Server 版本(SQL Server 2017 引入了新的复杂功能)以及您是否使用 Visual Studio / SSDT / SqlPackage`exe部署。我已经写了一系列关于这个主题的教程,展示了 2 个选项,它们都适用于所有版本的 SQL Server(嗯,从 2005 年到当前 - 目前是 2017 年),首先是:

SQLCLR vs. SQL Server 2017, Part 1: “CLR strict security” – The Problem

第 1 部分(直接在上面链接)解释了这种情况以及为什么 SQL Server 2017 中的新服务器范围设置是一个问题,因为缺乏通过 Microsoft 提供的工具(例如 Visual Studio)处理它的内置支持/固态硬盘。第 2 部分和第 3 部分是实际的解决方案。

【讨论】:

  • 感谢@Solomon 的建议,我很感激,请看我上面的3 cmets,打字太多,不得不添加几次评论。
【解决方案2】:

我使用 SQL Server 项目 dll 引用的 dll 中的 Web 服务客户端对象来完成这项工作。我试图对安全性采取积极主动的态度,并授予我的非对称密钥登录外部使用权而不是不安全的。一旦我授予登录不安全权限,它就能够正确调用 Web 服务。

感谢@Solomon 提供的关于安全的好建议。我想我会将我的经验在这里发布给任何可能有问题的人。

您可以使用此演练 (https://code.msdn.microsoft.com/Calling-WCF-Service-from-a-8071ceaa),但我将尝试添加本文遗漏的有关如何在您的项目中使用签名并在 SQL 中创建非对称密钥的内容。

  1. 创建库类型的 Visual Studio 项目并添加对 WCF 服务的 Web 引用。然后创建一个方法(确保它是静态的)来创建您的 Web 服务客户端对象并调用您的服务。

当您添加了用于调用 Web 服务的任何静态方法后编译此项目。

  1. 创建 SQL Server 数据库项目类型的 Visual Studio 项目,并添加对上一个库项目的 dll 的引用。使用上面的链接查看如何设置这个项目。 (注意,当我在本地进行引用然后将内容移动到服务器时,我确保我的 SQL Server 数据库项目具有库项目的 dll 引用的这些属性,复制本地 = true,特定版本 = false,生成 SQL 脚本 = false , Is Visible = true, Model Aware = true, and permission set = external(不确定这最后一个是否重要,因为无论如何我都必须授予对我的 sql 登录的不安全访问权限......)

  2. 我使用 windows SDK 中的 sn.exe 工具创建了我的 .snk 文件,该文件在 sql 中用于创建您的登录名,也用于签署之前的 2 个 VS 项目。 (或者,如果您已经了解创建签名程序集,请直接通过 Visual Studio 进行,然后在 SQL Server 中使用该 .snk)

  3. 我使用此链接https://www.codeproject.com/Articles/290249/Deploy-Use-assemblies-which-require-Unsafe-Externa(方法 2)来学习如何使用 sn.exe 工具以及如何设置非对称密钥和登录以在 SQL Server 中使用。注意(sn.exe 工具的位置对我而言与本文中的位置不同,对我而言,我必须转到位置:c:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\ NETFX 4.5.1 工具,这也可能因其他工具而异。

  4. 您必须做的最后一件事是重新配置您的数据库服务器以允许 CLR,这是在 SQL Server 中使用以下命令完成的:

    EXEC sp_configure 'clr enabled', '1'
    RECONFIGURE
    
  5. 关于启用 clr,我不确定这是否应该在存储过程中打开,然后再次关闭,(安全想法有人吗?)。

【讨论】:

  • 很高兴你能成功。不知道为什么需要UNSAFE。这些日子之一,我将不得不自己测试它。但很高兴知道。关于此处的步骤,我将删除步骤 3 - 6。签署程序集可以/应该在 Visual Studio 中完成,并且您可以自动化部署,甚至通过 Visual Studio / SSDT,并且从不使用 DLL。我更新了我的答案,链接到我写的一系列帖子的开头,展示了如何做到这一点。启用 CLR 是服务器范围的,而不是数据库设置。我不推荐第 4 步中的链接,因为第 5 步不需要USE。我不会在 proc 中打开/关闭服务器设置。
  • @Solomon,我相信第 3 步的原因是创建一个自定义密钥来签署我的程序集。由于我没有具体说明,我确实通过 Visual Studio 对程序集进行了签名,但我指向了我在步骤 3 中创建的自定义 .snk 文件。然后,在将 CLR 添加到 SQL Server 时,我使用了同一个文件。我没有意识到启用 CLR 是一个服务器范围的功能,我认为这是有道理的,但我想知道为什么他们不能在数据库级别上做得更细化,可能更安全?更新我的 SQL 语句。
  • Ryan:您不需要手动执行第 3 步。您可以在 Visual Studio 中处理这一切...转到项目属性,其中一个选项卡中有一个“签名”按钮...您可以在一个项目中创建一个新的 snk 文件(和密码保护成为 pfx),并且然后在其他项目(或 100 个项目)中引用 pfx..
  • 很酷,但是在创建非对称密钥时将其移植到 SQL 服务器怎么样?使用大师; create asymmetric key CLRExtensionKey from file = 'D:\Sample CLR\SampleCLRKey.snk' encryption by password = '@Str0ngP@$$w0rd' ,这是我发布的第二个链接的方法 2 的这一部分。
  • 您需要查看我在答案中链接的一系列帖子。我涵盖了允许您在 Visual Studio 中自动执行此操作的所有变体......并且由于您没有使用 SQL Server 2017,您可以转到第一篇或第二篇文章(至少是解决方案 1)中链接的文章我在 SQL Server Central 上写的文章,由于在 2017 年之前不需要证书,因此步骤更少。但是您不需要从文件创建程序集、非对称密钥或证书。永远不要从文件中创建。始终拥有一个完全独立的 SQL 脚本,没有外部依赖项。
【解决方案3】:

您可以遵循此存储库的相同示例......唯一的是它正在调用 Api。但它基本上与您需要修改一些东西的概念相同。 希望对你有帮助。

看看这个存储库https://github.com/geral2/SQL-APIConsumer。

第 1 步

CREATE DATABASE TestDB; GO

第 2 步

USE TestDB GO sp_configure 'clr enabled',1 RECONFIGURE GO

第 3 步

ALTER DATABASE TESTDB SET TRUSTWORTHY ON GO

第 4 步

CREATE ASSEMBLY [System.Runtime.Serialization] AUTHORIZATION dbo FROM N'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll' WITH PERMISSION_SET = UNSAFE--external_access GO

第 5 步

CREATE ASSEMBLY [Newtonsoft.Json] AUTHORIZATION dbo FROM N'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Newtonsoft.Json.dll' WITH PERMISSION_SET = UNSAFE go

【讨论】:

    猜你喜欢
    • 2015-12-28
    • 2016-06-14
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多