私有存储库认证

为了让 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 } 数据对象。当凭证被服务器批准或拒绝时,会分别调用已批准和已拒绝的方法。

可选的 configurestatus 方法是 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 。