包源映射是一种工具,可用于提高供应链安全性,尤其是在混合使用公共和专用包源时。
默认情况下,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 选项对话框启用
- 在 Visual Studio 中打开解决方案。
- 导航到
Package Source Mappings“选项”对话框。
从包管理器 UI
- 从列表中选择一个包,以在“详细信息”窗格中显示它。
- 按下
Configure按钮以打开“包源映射”选项页。
从 Visual Studio 选项对话框中
- 转到
ToolsVisual Studio 主工具栏中的菜单,然后选择NuGet Package Manager->Package Manager Settings。 - 导航到
Package Source Mappings页面。
有关管理 NuGet 包源映射的详细信息,请参阅 Visual Studio 中的 NuGet 选项。
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.Common、Contoso.Contracts |
确切的包 ID。 |
包模式优先级
当多个唯一模式与包 ID 匹配时,首选最具体的模式。 包 ID 模式始终具有最高优先级,而泛型 * 始终具有最低优先级。 对于包前缀模式,长度最长的具有优先权。
设置默认源
该 * 模式可用于声明事实默认源 - 这意味着任何与其他指定模式不匹配的包都将从该源还原,而不会引发错误。
主要使用来自nuget.org的包,并且只有几个内部包,或对所有内部包使用像Contoso.*这样的标准前缀时,此配置是有利的。
如果你的团队在安装内部包之前没有对包ID使用标准前缀或审核nuget.org包,那么将专用源设置为默认源将更好地满足你的需求。
注释
当请求的包已存在于全局包文件夹中时,不会发生源查找,并且将忽略映射。 请考虑为存储库声明 全局包文件夹 ,以获得此功能的全部安全优势。 为改进默认全局包文件夹的体验,计划进行下一次迭代。 若要详细了解包安装的工作原理,请参阅 概念文档。
开始
可通过 2 种方法 手动 或使用 NuGet.PackageSourceMapper 工具完全载入存储库。
手动入职
对于手动载入,可以执行以下步骤:
- 为存储库声明新的 全局包文件夹。
- 运行 dotnet 还原 以还原依赖项。
- 运行
dotnet list package --include-transitive以查看解决方案中的所有顶级和可传递包。- 对于 .NET Framework 项目使用
packages.config的情况,packages.config文件将包含一个所有直接包和传递包的平面列表。
- 对于 .NET Framework 项目使用
- 定义映射,使解决方案中的每个包 ID( 包括可传递包 )都与目标源的模式匹配。
- 运行 dotnet nuget locals global-packages -c 来清除全局包目录。
- 运行还原以验证是否已正确配置映射。 如果映射未完全涵盖解决方案中的每个包 ID,错误消息将帮助你识别问题。
- 还原成功后,即可完成! (可选)考虑:
- 使用更广泛的包 ID 前缀或尽可能 设置默认源 ,将配置简化为更少的声明。
- 通过检查 全局包文件夹中的元数据文件或查看还原日志来验证每个包的源是否已还原。
使用工具自动载入
许多存储库具有大量包,并且手动执行工作可能非常耗时。 NuGet.PackageSourceMapper 工具可以根据项目的已知包和源自动生成 NuGet.config。
包源映射器工具要求你已完成一个成功的包还原,它将读取生成过程中生成的每个相应 .nupkg.metadata 文件,以最好地了解如何映射各自的包和源。 工具不仅涵盖顶级依赖项,它还在生成映射时会考虑所有可传递依赖项。
工具有多种选项如何根据需求生成映射模式,请查看 博客文章 和工具 的自述说明 以了解更多详细信息。
若要了解源映射的外观,请参阅我们的 示例存储库。
注释
- 没有用于管理包源映射配置的 nuget.exe 或 dotnet.exe 命令,请参阅 NuGet/Home#10735。
- 包安装时没有映射包的方法,请参阅 NuGet/Home#10730。
- 使用
DotNetCoreCLI@2Azure Pipelines 任务时存在限制,可以在源映射配置中使用feed-前缀来解决此问题。 建议使用NuGetAuthenticate满足您的身份验证需求,并直接从脚本任务中调用 dotnet CLI。 请参阅 microsoft/azure-pipelines-tasks#15542。