私有存储库认证

为了让 Antora 访问私有存储库,您需要为想要使用的任何私有存储库 URL 提供身份验证凭据。这些凭证可以外部化,这样它们就不必硬编码到剧本中。本页面介绍了将凭据传递给 Antora 的各种方法,包括内置的 git 凭据存储库、自定义凭据存储库,甚至是您自己的凭据管理器。

让我们从查看默认情况下 Antora 接受的身份验证凭据类型开始,然后转到如何设置和使用它们。

认证类型

Antora 可以使用 HTTP 基本身份验证来认证私有代码库。HTTP 基本身份验证需要向服务器发送凭据(经过 HTTPS 加密)来验证您的身份。认证凭据包括用户名/密码对或访问( OAuth 2.0 )令牌。

用户名/密码对通常是您用于登录存储库的服务(如 GitHub、GitLab 等)的凭据。如果用户名或密码包含在 URL 中具有特殊含义的字符,例如 / 、# 和 : ,则这些字符必须进行 URL编码(即百分号编码),以避免 URL 解析器错误解释它们。请注意,尽管一些 GIT 主机支持这种身份验证方式,但其他主机可能不支持。您可以尝试使用访问令牌来获得更好的体验。

当您的帐户启用两步验证( 2FA )时,您无法使用用户名/密码对来验证私有库。当您尝试时,您将收到 401 HTTP Basic: Access Denied 错误。

无论出现何种情况,如果 GIT 主机不允许您使用用户名/密码对进行身份验证,则需要改用访问令牌。

有两种类型的访问令牌:个人访问令牌和部署令牌。

  • 个人访问令牌绑定到用户,并授予对您的帐户可以访问的任何私有存储库的访问权限(受令牌本身的范围设置的限制)。

  • 部署令牌(不是部署密钥)绑定到项目(即,存储库),并授予对单个存储库的访问权限(取决于令牌本身的范围设置)。

由于部署密钥需要使用 SSH 身份验证,而 Antora 中的 git 客户端不支持 SSH 身份验证,因此无法与 Antora 一起使用。

通常,您在自己的机器上使用单个个人访问令牌,而在 CI 服务器上使用一个或多个部署令牌。

要为 GitHub 创建访问令牌,请参阅 为命令行创建个人访问令牌。目前,GitHub 不支持部署令牌。要为 GitLab 创建访问令牌,请参阅 个人访问令牌 和 部署令牌。对于 Bitbucket ,请创建具有对存储库的读取权限的 应用程序密码。

接下来,让我们看看如何通过默认的 git 凭证存储库向 Antora 的内置凭证管理器提供这些凭据。

使用默认的git凭证存储库提供凭证

Antora 的内置凭证管理器默认会自动在 git 凭证存储库(一个数据库文件)中检查凭证。git 凭证存储库的默认路径为,如果此路径不存在,则为 HOME/.git−credentials ,如果此路径不存在,则为 XDG_CONFIG_HOME/git/credentials 。

由于 Antora 会在 git 主机请求凭证时自动查询凭证管理器(也就是按需查询),因此您不必直接在 playbook 中指定凭证。实际上,playbook 中的私有内容源看起来与公共内容源一样。下面是您的 playbook 中的私有内容源可能会如何呈现:

content:
  sources:
  - url: https://hostname/your-org/private-repository

当 Git 主机通知 Antora 需要身份验证的 URL 时,Antora 将在凭证存储库中查找具有匹配上下文的条目。如果在凭证存储库中找到了协议(例如 https)和主机名(以及可选的存储库路径),则这些凭据将返回给 Antora 的凭证管理器,并传递给 Git 服务器。

凭证存储库包含零个或多个基于行的条目。如果您需要为单个主机名指定多个凭据(例如多个部署令牌),请将每个条目放在其自己的行上。每个条目的结构如下:

https://<credentials>@<hostname>

<credentials> 可以是一个用户名/密码对 (username:password),或一个访问令牌 (token:)。 <hostname> 是 Git 服务器的地址(例如 github.com)。

如果用户名或密码包含在 URL 中具有特殊含义的字符,例如 /、# 或 :,这些字符必须进行 URL 编码。( @ 在用户名或密码中没有特殊含义)。通常情况下,将用户名和密码组件进行 URL 编码通常是安全的。此要求仅适用于在 git 凭证存储库中定义的 URL。

要对组件进行 URL 编码,请在浏览器中打开 JavaScript 控制台,并运行 encodeURIComponent('<component>'),其中 <component> 是用户名或密码值。如果不同,请使用打印结果代替您的用户名或密码。例如,my#password 的 URL 编码版本是 my%23password。

您可以使用系统 git 命令交互式地填充凭据存储库,也可以直接编辑凭据存储库。让我们从交互式方法开始。

交互式地填充凭据存储

您可以使用 git 命令交互式地填充凭据存储库。这种方法特别有用,因为它允许您验证凭证是否被 git 服务器接受。

首先,选择要与 Antora 一起使用的私有存储库的 URL 。接下来,在终端中,为需要从 Antora 访问的每个私有存储库运行以下命令:

git config --global credential.helper store && echo -n 'Repository URL: ' && read REPLY && git ls-remote -h $REPLY > /dev/null

命令执行的步骤如下:

  1. 全局(临时)启用 git 凭据存储。

  2. 提示您输入私有存储库的URL。

  3. 与私人存储库进行通信,从而触发您的凭据提示。

    NOTE

    如果没有提示您输入凭据,则表示您的凭据已经存储。

  4. 将凭据存储在 $HOME/.git-credentials 中(并为其分配适当的权限)。

如果该脚本成功,您可以使用 Antora 中适用的私有存储库,而无需进一步配置。

恢复git配置

上面的交互式脚本修改了 git 设置,以便全局启用凭据存储。如果您没有使用 Antora 以外的凭据存储,请运行以下命令再次禁用它:

git config --global --remove-section credential

更改此设置不会影响 Antora 使用凭据存储的方式。它只影响本地 git 客户端的行为。

如果交互式方法不适合您,您可以直接填充凭据存储。让我们试一试。

直接填充凭据存储

要直接向 git 凭证存储库添加凭据,请创建文件 $HOME/.git-credentials 并在编辑器中打开它。将每个唯一的凭据集(即,用户名/密码对或访问令牌加上主机名和可选的存储库路径)都放在自己的一行上。如果您正在使用单个 Git 主机和个人访问令牌,则只需要一个条目。如果您正在使用多个 Git 主机或多个部署令牌,则需要多个条目。

下面是一个使用用户名/密码对的实例条目:

https://octocat:ilovegit@github.com

下面是一个使用令牌的示例(注意令牌后面的末尾 : ):

https://abcdefg0123456:@github.com

要为给定的存储库使用不同的凭据,您可以向条目添加存储库路径(即 <repo> ),以使匹配更加严格。(存储库路径中的 .git 文件扩展名是可选的)。

https://<credentials>@<hostname>/<repo>

下面是一个特定存储库路径的示例:

https://octocat:ilovegit@github.com/octocat/Hello-World

下面是几个流行的 git 主机的示例(您可以用实际值替换粗体中的占位符)

https://{TOKEN}:@github.com/org/project-docs
https://oauth2:{TOKEN}@gitlab.com/org/project-docs.git
https://gitlab+deploy-token-{TOKEN_ID:TOKEN}@gitlab.com/org/project-docs.git
https://x-oauth-token:{TOKEN}@bitbucket.org/org/project-docs.git
https://{USERNAME:APP_PASSWORD}@bitbucket.org/org/project-docs.git
NOTE

指定存储库路径是可选的。如果您不包含它,那么凭证将用于共享同一 git 主机的所有 url 。

CAUTION

您可能需要附加 .git 文件扩展名,这取决于您为内容源使用的 URL 格式,以及您是否在剧本中配置了 确保git后缀 键。

NOTE

请注意,令牌根据 Git 主机的不同位于 URL 中的不同位置。有关更多详细信息,请参阅 OAuth2 格式。如果您正在使用 Bitbucket 应用密码,请注意必须包括您自己的用户名(使用格式 USERNAME:APP_PASSWORD )。

要确保凭证文件受到保护,请立即设置其文件权限,使其不能被其他人读取。

chmod 600 $HOME/.git-credentials

指定自定义git凭证存储路径

您可以使用 --git-credentials-path 命令行选项或 GIT_CREDENTIALS_PATH 环境变量,指示 Antora 在不同位置查找凭证存储库文件,而不是使用默认路径中的凭证存储库。

下面是一个使用 CLI 选项指定相对于 playbook 文件的路径的示例:

antora --git-credentials-path=./.git-credentials antora-playbook.yml

您还可以使用 git 键下的 credertials.path 键在剧本中直接指定此位置。

通过环境变量传递凭据

除了从文件中读取凭据外,您还可以让 Antora 直接从名为 GIT_CREDENTIALS 的环境变量中读取凭据。以下是一个示例,演示了该概念:

export GIT_CREDENTIALS='https://octocat:ilovegit@github.com'
antora antora-playbook.yml

您甚至可以将其减少为一行(仅定义命令范围的环境变量)。

GIT_CREDENTIALS='https://octocat:ilovegit@github.com' antora antora-playbook.yml

在使用 Windows 命令提示符时,需要使用 set 命令定义环境变量:

C:\> set "GIT_CREDENTIALS=https://octocat:ilovegit@github.com" && antora antora-playbook.yml

此策略 在环境变量可以得到保护 的 CI 环境中非常有用。它也是在您自己的机器上生成站点时向 Antora 传递凭据的一种快速而非正式的方式。在使用环境变量时,多个条目可以用逗号或换行符分隔。例如:

GIT_CREDENTIALS='https://my-github-token:@github.com,https://oauth2:my-gitlab-token@gitlab.com' antora antora-playbook.yml

导出环境变量使您不必在每次运行 Antora 时都输入它。

在URL中编码凭证(不推荐)

将凭据传递给凭据管理器的另一种选择是直接在剧本中列出的 URL 中对它们进行编码。由于此选项不会触发质询-响应工作流,因此 Antora 会自动假定存储库是私有的。

WARNING

不建议使用此策略,除非您使用占位符注入真正的凭据,如本节末尾所述。

如果需要,Antora 会提取出跟在主机名前面的凭证(即,username:password@ 或 token@),并使用它们代表您执行身份验证。

以下是几个流行的 Git 主机的示例(您需要将这些示例中的粗体占位符替换为实际值)

Example 1. Example 1. antora-playbook.yml (fragment)
content:
  sources:
  - url: https://{TOKEN}:@github.com/org/project-docs
  - url: https://oauth2:{TOKEN}@gitlab.com/org/project-docs.git
  - url: https://gitlab+deploy-token-{TOKEN_ID:TOKEN}@gitlab.com/org/project-docs.git
  - url: https://x-oauth-token:{TOKEN}@bitbucket.org/org/project-docs.git
  - url: https://{USERNAME:APP_PASSWORD}@bitbucket.org/org/project-docs.git
NOTE

请注意,令牌根据 Git 主机的不同位于 URL 中的不同位置。有关更多详细信息,请参阅 OAuth2 格式。如果您正在使用 Bitbucket 应用密码,请注意必须包括您自己的用户名(使用格式 USERNAME:APP_PASSWORD)。

这种方法的缺点是需要将凭据直接放入剧本(playbook)文件中。不幸的是,Antora 还不支持解析剧本文件中的环境变量。但是,您可以通过使用脚本将 playbook 文件中环境变量的引用替换为其值来模拟此行为。假设您在 playbook 文件中定义了以下源代码

Example 2. Example 2. antora-playbook.yml (fragment)
content:
  sources:
  - url: https://$GITHUB_TOKEN:@github.com/org-name/project-docs

如果您正在使用多个需要相同凭证的私有存储库,您可以在 git 密钥下定义凭证,如下所示

Example 3. Example 3. antora-playbook.yml (fragment)
git:
  credentials:
    contents: https://$GITHUB_TOKEN:@github.com

然后,您可以使用以下脚本展开对环境变量的引用,您可以在调用 Antora 之前在 CI 中运行环境变量:

sed -i s/\$GITHUB_TOKEN/$GITHUB_TOKEN/ antora-playbook.yml
antora antora-playbook.yml

尽管有这种解决方法,我们仍然建议使用前面描述的凭据存储集成。

配置自定义凭据管理器

Antora 使用的 git 客户端 isomorphic-git ,为查找身份验证凭据提供了一个 可插拔的凭据管理器 。Antora 提供了该插件的默认实现。正如您在之前的部分中看到的那样,此实现假定 Antora 可以直接以明文的方式访问凭据,通过文件或环境变量。如果此安排不符合您的安全要求,则可以使用自己的凭据管理器替换内置的凭据管理器。

要编写自定义凭证管理器,请导出一个实现以下方法的 JavaScript 对象:

Example 4. Example 4. API for custom git credential manager
configure ({ config, startDir })
async fill ({ url })
async approved ({ url })
async rejected ({ url, auth })
status ({ url })

查找凭证的方法是 fill 。它必须返回 { username,password } 或 { token } 数据对象。当凭证被服务器批准或拒绝时,会分别调用已批准和已拒绝的方法。

可选的 configure 和 status 方法是 Antora 特有的,扩展了 isomorphic-git 中凭证管理器的功能。如果定义了 configure 方法,则每次 Antora 启动时都会调用它,提供初始化步骤,如定义属性。如果可用,Antora 会使用 status 方法查找是否为给定的 URL 请求了身份验证。

要激活自定义凭证管理器,首先在专用的 JavaScript 文件中编写它,并将其配置为默认导出。

Example 5. Example 5. custom-git-credential-manager.js
module.exports = {
  async fill ({ url }) { ... },
  async approved ({ url }) { ... },
  async rejected ({ url, auth }) { ... },
}

然后用剧本注册凭据管理器,如下所示:

git:
  plugins:
    credential_manager: ./custom-git-credential-manager.js

或者,您可以将插件配置为自我注册:

Example 6. Example 6. custom-git-credential-manager.js
'use strict'

const git = require('isomorphic-git')

if (!git.cores) git.cores = new Map()
git.cores.set('antora', new Map().set('credentialManager', {
  async fill ({ url }) { ... },
  async approved ({ url }) { ... },
  async rejected ({ url, auth }) { ... },
}))

请注意,在此情况下,插件名称为 credentialManager 而不是 credential_manager 。这是因为 playbook builder 会自动为我们驼峰命名键名,这是 git 客户端期望的键名。

当使用自注册凭证管理器时,您可以使用 -r 选项将其传递给 Antora,而不是在 playbook 中注册它:

antora -r ./custom-git-credential-manager.js antora-playbook.yml

如果您已经使用 npm 全局安装了 Antora,那么您可能会遇到使用自注册凭证管理器时出现问题的情况。或者您会遇到错误 Cannot find module 'isomorphic-git' ,或者您的自定义凭证管理器不会被调用。要解决此问题,请设置 NODE_PATH 环境变量,告诉 Node.js 在哪里查找 Antora 的依赖项:

NODE_PATH=$(npm -g list --parseable=true @antora/site-generator)/node_modules antora -r ./custom-git-credential-manager.js antora-playbook.yml

另一种解决方案是在本地安装 Antora(即在 package.json 文件的依赖项中添加 Antora 包并运行 npm i )。

由于自注册插件更加复杂,我们将使用在 playbook 中注册插件的示例进行下一步操作。

从git获取凭证

Git 提供了一个名为 git credential 的命令,它作为一个简单的接口来存储和检索凭证,使用系统特定的辅助程序以与 git 本身相同的方式。它还可以提示用户输入用户名和密码。我们可以在自定义凭证管理器中使用此命令,以允许 Antora 委托 git 查找凭证(从而与用户自己的 git 设置集成)。

让我们首先创建一个辅助函数,该函数通过 git 凭据 fill 与系统 git 进行接口,以检索 URL 的凭证:

Example 7. Example 7. system-git-credential-manager.js
'use strict'

const { spawn } = require('child_process')

function callGitCredentialFill (url) {
  const { protocol, host } = new URL(url)
  return new Promise((resolve, reject) => {
    const output = []
    const process = spawn('git', ['credential', 'fill'])
    process.on('close', (code) => {
      if (code) return reject(code)
      const { username, password } = output.join('\n').split('\n').reduce((acc, line) => {
        if (line.startsWith('username') || line.startsWith('password')) {
          const [key, val] = line.split('=')
          acc[key] = val
        }
        return acc
      }, {})
      resolve(password ? { username, password } : username ? { token: username } : undefined)
    })
    process.stdout.on('data', (data) => output.push(data.toString().trim()))
    process.stdin.write(`protocol=${protocol.slice(0, -1)}\nhost=${host}\n\n`)
  })
}

接下来,让我们创建一个凭据管理器,该管理器使用此函数来填充 URL 的凭据:

// ...

module.exports = {
  configure () {
    this.urls = {}
  },
  async fill ({ url }) {
    this.urls[url] = 'requested'
    return callGitCredentialFill(url)
  },
  async approved ({ url }) {
    this.urls[url] = 'approved'
  },
  async rejected ({ url, auth }) {
    this.urls[url] = 'rejected'
    const data = { statusCode: 401, statusMessage: 'HTTP Basic: Access Denied' }
    const err = new Error(`HTTP Error: ${data.statusCode} ${data.statusMessage}`)
    err.name = err.code = 'HttpError'
    err.data = data
    if (auth) err.rejected = true
    throw err
  },
  status ({ url }) {
    return this.urls[url]
  },
}

最后,我们需要向剧本注册凭据管理器:

git:
  plugins:
    credential_manager: ./system-git-credential-manager.js

现在,Antora 将委托给系统 git 来填写 URL 的凭据:

antora antora-playbook.yml

根据凭据是否被服务器批准或拒绝,留给读者一个练习来存储或删除凭据(提示:使用批准和拒绝的方法再次调用 git 凭据)。

SSH身份验证

自 Antora 2.0 以来,Antora 不再支持使用 SSH 代理进行公钥/私钥身份验证。相反,Antora 会将 playbook 中的 git SSH URL 透明地转换为 HTTPS URL ,并使用凭证管理器进行身份验证。这意味着您可以在 playbook 文件中交替使用 SSH URL 和 HTTPS URL ,但最终 git 客户端将通过 HTTPS 进行通信。如果由于某种原因,这种自动转换不起作用,则需要更新 playbook 文件以使用正确的 HTTPS URL 。