【问题标题】:Programmatically building SSIS packages with EncryptSensitiveWithPassword and package-level connection managers使用 EncryptSensitiveWithPassword 和包级连接管理器以编程方式构建 SSIS 包
【发布时间】:2014-06-18 21:33:59
【问题描述】:

我正在尝试使用已保存的项目级连接管理器密码自动部署 SSIS 项目。这些包连接到仅提供 SQL 登录的第三方数据库,因此在这种情况下集成安全性不是一个选项。我使用this 作为参考,因为它似乎适用于相同的用例。我已经编译并运行了 MSBuild 任务,以及一个 MSBuild 项目文件。我可以通过命令行毫无问题地构建和部署项目。

问题

当我部署通过 Visual Studio 生成的 ispac 文件时,我可以毫无问题地运行这些包。但是,当我部署由 MSBuild 任务生成的 ispac 并尝试运行时,我收到以下验证错误:

错误:SSIS 错误代码 DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER。对连接管理器“”的 AcquireConnection 方法调用失败,错误代码为 0xC0202009。在此之前可能会发布错误消息,其中包含有关 AcquireConnection 方法调用失败原因的更多信息。

错误:SSIS 错误代码 DTS_E_OLEDBERROR。发生 OLE DB 错误。错误代码:0x80040E4D。 OLE DB 记录可用。来源:“Microsoft SQL Server Native Client 11.0”Hresult:0x80040E4D 描述:“用户''登录失败。”

如果我将其中一个包更改为使用包级连接管理器连接到同一台服务器,则密码将被保留,我可以运行该特定包。

连接管理器存储在.conmgr 文件中,DTS:Password 节点被标记为敏感并包含加密密码。据我所知,问题出在构建任务代码中。 code for the build task 执行以下操作:

  • 反序列化.dtproj文件,获取项目中的连接管理器文件路径列表

  • 创建一个新的Microsoft.SqlServer.Dts.Runtime.Project(据我所知,它与生成的.ispac 而不是.dtproj“项目”相关联)

  • 对于每个连接管理器文件,调用project.ConnectionManagerItems.Add(<connection manager name>, <.conmgr file name>)

  • 通过cm.Load(NULL, <stream of the conmgr file>)加载返回的ConnectionManagerItem

我假设在最后两个步骤中的某个地方,密码没有被反序列化,并且新的Project 在没有密码的情况下添加了连接管理器。我一直在搜索集成服务开发人员指南,但它似乎更侧重于以编程方式从头开始创建连接管理器,而不是加载具有需要解密数据的现有连接管理器。

更新 根据@billinkc 的建议,我解压缩了生成的 ispac 文件以比较连接管理器的保存方式。 MSBuild 生成的与 Visual Studio 生成的相同,只是缺少DTS:Password 元素。这支持了我的理论,即将连接管理器添加到Microsoft.SqlServer.Dts.Runtime.Project 的代码要么没有反序列化,要么没有序列化密码。不过,我在 SSIS 的可编程性方面还不够深入,所以我不知道从哪里开始。相关文档**没有提供太多见解。

** Project, ConnectionManagerItem, Working with connection managers programmatically, Adding connection managers programmatically

【问题讨论】:

  • 请原谅我在 SSIS 中不太使用 SQL 登录。在 Visual Studio 中,如果您在那里构建项目,ispac 是否可以正常构建?这可能是试图辨别 VS 构建的 .ispac 文件具有哪些 msbuild 版本没有的问题。这也可能是 codeplex 任务中的一个缺陷,因此您也可以将此问题交叉发布到该列表中。
  • @billinkc 是的,我可以通过 MSBuild 和 VS 创建 ispac。 VS 版本有效。
  • @billinkc 我查看了生成的 ispac 文件(没有意识到它们只是 zip 档案:) 并更新了我的问题
  • 非常好,那么这对于 codeplex 的人来说听起来像是一个缺陷。这是一个有趣的问题,我希望我能提供帮助。我同意这样的假设,即连接管理器的反序列化,但它是如何影响的,我也不知道。我看看我能不能加入@mattmasson 他是我的欧比旺克诺比
  • 如果您将/verbosity:diag 添加到您的msbuild 调用中,会出现什么有趣的事情吗?我想知道他们是否不需要在var cmXml = 之后使用 Project.password 来解密 XML,如果包保护级别是 PasswordNeeded 是真的。

标签: ssis msbuild sql-server-2012


【解决方案1】:

我只是不能放手,以简单(智能)的方式来做,所以我掌握了加密知识(几乎没有)和 MSDN 中的一行**,我开始尝试解密加密元素。经过一番反复试验,我终于让它工作了:

private string DecryptConnectionManagerPassword(string connectionManagerPath)
{
    // Load the xml and get the encrypted DTS:Password node
    XmlDocument cmDocument = new XmlDocument();
    cmDocument.Load(connectionManagerPath);

    XmlElement passwordElement = cmDocument.GetElementsByTagName("DTS:Password")[0] as XmlElement;

    // Create byte arrays with the data we'll need
    byte[] salt = Convert.FromBase64String(passwordElement.GetAttribute("p4:Salt"));
    byte[] iv = Convert.FromBase64String(passwordElement.GetAttribute("p4:IV"));
    byte[] cipherText = Convert.FromBase64String(passwordElement.InnerText);
    byte[] password = System.Text.Encoding.ASCII.GetBytes(ProjectPassword);

    // Create the cipher key
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, salt);
    byte[] key = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, iv);

    // Decrypt the cipher text
    var csp = new TripleDESCryptoServiceProvider();
    csp.Mode = CipherMode.CBC;
    csp.IV = iv;
    csp.Key = key;

    var plainTextBytes = new byte[512];
    var decryptor = csp.CreateDecryptor();
    decryptor.TransformBlock(cipherText, 0, cipherText.Length, plainTextBytes, 0);

    // Get convert to a string and extract password
    var plainText = new string(System.Text.Encoding.ASCII.GetChars(plainTextBytes));

    // the decrypted text doesn't come out as valid xml
    // so I use a regex to extract the password. Obviously dangerous.
    var regEx = new Regex(">(.*)<");
    var matches = regEx.Match(plainText);

    return matches.Captures[1].Value;
}

从那里开始,只需在连接管理器上设置Password 属性,生成的 ispac 包含带有加密密码元素的连接管理器。

** Also, for the protection levels that use a password, Integration Services uses the Triple DES cipher algorithm with a key length of 192 bits, available in the .NET Framework Class Library (FCL).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多