软件包源映射

包源映射是一种工具,可用于提高供应链安全性,尤其是在混合使用公共和专用包源时。

默认情况下,NuGet 会在需要下载包时搜索所有配置的包源。 当一个包存在于多个源上时,可能无法确定将从哪个源下载该包。 使用包源映射,您可以为每个包筛选 NuGet 要搜索的源。

我们还提供了其他 最佳做法 的建议,可帮助你强化供应链免受攻击。

NuGet 6.0 中添加了包源映射。 从 Visual Studio 17.5 开始,可以使用 Visual Studio 选项对话框添加和删除包源映射。 有关所有 Visual Studio NuGet 选项的详细信息,请参阅 Visual Studio 中的 NuGet 选项

Visual Studio 支持

Visual Studio 软件包源映射 工具中的支持 -> 选项 包管理器 UI 中的支持
17.0 - 17.4 ✅ 可用 ❌ 不可用 ❌ 不可用
17.5 ✅ 可用 ✅ 可用 ❌ 不可用
17.7 预览版 3 ✅ 可用 ✅ 可用 ✅ 显示的状态

此功能适用于所有 NuGet 集成工具。

较旧的工具将忽略包源映射配置。 若要使用此功能,请确保所有生成环境都使用兼容的工具版本。

只要使用兼容的工具,包源映射将应用于所有项目类型(包括 .NET Framework)。

视频指南

有关包源映射功能的视频概述,可以在 YouTube 上观看 使用包源映射保护您的 NuGet 包 的视频。

启用包源映射

若要选择加入此功能,必须有一个 nuget.config 文件。 在存储库的根目录中拥有一个 nuget.config 被视为最佳做法。 有关详细信息 ,请参阅nuget.config 文档

使用 Visual Studio 选项对话框启用

  1. 在 Visual Studio 中打开解决方案。
  2. 导航到 Package Source Mappings “选项”对话框。

从包管理器 UI

  • 从列表中选择一个包,以在“详细信息”窗格中显示它。
  • 按下Configure按钮以打开“包源映射”选项页。

Visual Studio 中的 NuGet 包管理器窗口显示所选包,并在“包源映射已关闭”状态周围突出显示了“配置”按钮。

从 Visual Studio 选项对话框中

  • 转到 Tools Visual Studio 主工具栏中的菜单,然后选择 NuGet Package Manager ->Package Manager Settings
  • 导航到 Package Source Mappings 页面。

有关管理 NuGet 包源映射的详细信息,请参阅 Visual Studio 中的 NuGet 选项

NuGet 包管理器窗口将刷新并反映所选包的源映射的新状态。 Visual Studio 中的 NuGet 包管理器窗口显示具有“找到的包源映射”状态和“配置”按钮的所选包。

通过手动编辑启用 nuget.config

  • nuget.config 文件中声明所需的包源。
  • 在源声明之后,添加一个 <packageSourceMapping> 元素,指定每个源的所需映射。
  • 为每个正在使用的源声明一个 packageSource 元素。
    • 根据需要添加任意数量的模式。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <!-- Define the package sources, nuget.org and contoso.com. -->
  <!-- `clear` ensures no additional sources are inherited from another config file. -->
  <packageSources>
    <clear />
    <!-- `key` can be any identifier for your source. -->
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="contoso.com" value="https://contoso.com/packages/" />
  </packageSources>
  
  <!-- Define mappings by adding package patterns beneath the target source. -->
  <!-- Contoso.* packages and NuGet.Common will be restored from contoso.com,
       everything else from nuget.org. -->
  <packageSourceMapping>
    <!-- key value for <packageSource> should match key values from <packageSources> element -->
    <packageSource key="nuget.org">
      <package pattern="*" />
    </packageSource>
    <packageSource key="contoso.com">
      <package pattern="Contoso.*" />
      <package pattern="NuGet.Common" />
    </packageSource>
  </packageSourceMapping>
</configuration>

当存在不同级别的多个文件(计算机级别、用户级别、存储库级别)时,包源映射设置将遵循 nuget.config

包源映射规则

为了获得最大的灵活性和控制,NuGet 要求所有包都通过明确定义的优先级匹配包模式。

包装模式要求

所有请求的包都必须通过匹配定义的包模式映射到一个或多个源。 换句话说,定义元素 packageSourceMapping 之后,必须明确指定每个包——包括可传递包——要从哪个源进行还原。

  • 顶级 包和可传递 包必须匹配定义的模式。 顶级包及其依赖项没有必须来自相同来源的要求。
  • 可以在多个源上定义相同的 ID 模式,这样就允许从定义该模式的任何源中恢复匹配的包 ID。 但是,不建议这样做,因为对恢复的可预测性的影响(给定的包可能来自多个源)。 如果信任所有各自的源,这可能是一个有效的配置。

包模式语法

图案 示例语法 Description
软件包前缀模式 *NuGet.* 必须以 * 结尾,其中 * 匹配 0 个或多个字符。 * 是允许的最短前缀模式,并匹配所有包 ID。
包 ID 模式 NuGet.CommonContoso.Contracts 确切的包 ID。

包模式优先级

当多个唯一模式与包 ID 匹配时,首选最具体的模式。 包 ID 模式始终具有最高优先级,而泛型 * 始终具有最低优先级。 对于包前缀模式,长度最长的具有优先权。

包模式优先级示例

设置默认源

* 模式可用于声明事实默认源 - 这意味着任何与其他指定模式不匹配的包都将从该源还原,而不会引发错误。 主要使用来自nuget.org的包,并且只有几个内部包,或对所有内部包使用像Contoso.*这样的标准前缀时,此配置是有利的。

如果你的团队在安装内部包之前没有对包ID使用标准前缀或审核nuget.org包,那么将专用源设置为默认源将更好地满足你的需求。

注释

当请求的包已存在于全局包文件夹中时,不会发生源查找,并且将忽略映射。 请考虑为存储库声明 全局包文件夹 ,以获得此功能的全部安全优势。 为改进默认全局包文件夹的体验,计划进行下一次迭代。 若要详细了解包安装的工作原理,请参阅 概念文档。

开始

可通过 2 种方法 手动 或使用 NuGet.PackageSourceMapper 工具完全载入存储库。

手动入职

对于手动载入,可以执行以下步骤:

  1. 为存储库声明新的 全局包文件夹
  2. 运行 dotnet 还原 以还原依赖项。
  3. 运行 dotnet list package --include-transitive 以查看解决方案中的所有顶级和可传递包。
    • 对于 .NET Framework 项目使用 packages.config 的情况,packages.config 文件将包含一个所有直接包和传递包的平面列表。
  4. 定义映射,使解决方案中的每个包 ID( 包括可传递包 )都与目标源的模式匹配。
  5. 运行 dotnet nuget locals global-packages -c 来清除全局包目录。
  6. 运行还原以验证是否已正确配置映射。 如果映射未完全涵盖解决方案中的每个包 ID,错误消息将帮助你识别问题。
  7. 还原成功后,即可完成! (可选)考虑:

使用工具自动载入

许多存储库具有大量包,并且手动执行工作可能非常耗时。 NuGet.PackageSourceMapper 工具可以根据项目的已知包和源自动生成 NuGet.config。

包源映射器工具要求你已完成一个成功的包还原,它将读取生成过程中生成的每个相应 .nupkg.metadata 文件,以最好地了解如何映射各自的包和源。 工具不仅涵盖顶级依赖项,它还在生成映射时会考虑所有可传递依赖项。

工具有多种选项如何根据需求生成映射模式,请查看 博客文章 和工具 的自述说明 以了解更多详细信息。

若要了解源映射的外观,请参阅我们的 示例存储库

注释

  • 没有用于管理包源映射配置的 nuget.exe 或 dotnet.exe 命令,请参阅 NuGet/Home#10735
  • 包安装时没有映射包的方法,请参阅 NuGet/Home#10730
  • 使用 DotNetCoreCLI@2 Azure Pipelines 任务时存在限制,可以在源映射配置中使用 feed- 前缀来解决此问题。 建议使用 NuGetAuthenticate 满足您的身份验证需求,并直接从脚本任务中调用 dotnet CLI。 请参阅 microsoft/azure-pipelines-tasks#15542