私有存储库认证
为了让 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 编码,请在浏览器中打开 JavaScript 控制台,并运行 |
您可以使用系统 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
命令执行的步骤如下:
-
全局(临时)启用 git 凭据存储。
-
提示您输入私有存储库的URL。
-
与私人存储库进行通信,从而触发您的凭据提示。
- NOTE
-
如果没有提示您输入凭据,则表示您的凭据已经存储。
-
将凭据存储在
$HOME/.git-credentials
中(并为其分配适当的权限)。
如果该脚本成功,您可以使用 Antora 中适用的私有存储库,而无需进一步配置。
如果交互式方法不适合您,您可以直接填充凭据存储。让我们试一试。
直接填充凭据存储
要直接向 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
要确保凭证文件受到保护,请立即设置其文件权限,使其不能被其他人读取。
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 主机的示例(您需要将这些示例中的粗体占位符替换为实际值)
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 文件中定义了以下源代码
content:
sources:
- url: https://$GITHUB_TOKEN:@github.com/org-name/project-docs
如果您正在使用多个需要相同凭证的私有存储库,您可以在 git 密钥下定义凭证,如下所示
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 对象:
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
文件中编写它,并将其配置为默认导出。
module.exports = {
async fill ({ url }) { ... },
async approved ({ url }) { ... },
async rejected ({ url, auth }) { ... },
}
然后用剧本注册凭据管理器,如下所示:
git:
plugins:
credential_manager: ./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 的凭证:
'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 凭据)。