私有存储库身份验证
为了让 Antora 访问私有存储库,您必须为 playbook 中使用的任何私有存储库 URL 提供身份验证凭据。这些凭据可以外部化,这样就不必将它们硬编码到 playbook 中。本页面涵盖了您可以将凭据传递给 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 客户端不支持,因此无法将部署密钥用于 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
当Antora收到git主机通知需要身份验证的URL时,它将在凭据存储库中查找匹配的条目。Antora使用URL作为键来查找匹配项。如果在凭据存储库中找到协议(例如https
)和主机名(以及可选的存储库路径),则这些凭据将返回给Antora的凭据管理器,并传递给git服务器。
凭据存储库包含零个或多个基于行的条目。如果需要为单个主机名指定多个凭据(例如多个部署令牌),请将每个条目放在单独的行上。每个条目的结构如下:
https://<凭据>@<主机名>
<凭据>
可以是用户名/密码对(username:password
)或访问令牌(token:
)。<主机名>
是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。
-
与私有存储库通信,触发要求输入您的凭据。
如果没有提示您输入凭据,这意味着您的凭据已经存储。 -
将凭据存储在$HOME/.git-credentials中(并分配适当的权限)。
如果此脚本成功,您可以在Antora中使用适用的私有存储库,而无需进一步配置。
如果交互式方法对您不起作用,您可以直接填充凭据存储库。让我们尝试一下。
直接填充凭据存储库
要直接向git凭据存储库添加凭据,请创建文件$HOME/.git-credentials并在编辑器中打开它。将每组唯一的凭据(即用户名/密码对或访问令牌加上主机名和可选的存储库路径)放在单独的行上。如果您使用单个git主机和个人访问令牌,则只需要一个条目。如果您使用多个git主机或多个部署令牌,则需要多个条目。
以下是使用用户名/密码对的示例条目:
https://octocat:ilovegit@github.com
以下是使用令牌的示例(注意令牌后面的尾随:
):
https://abcdefg0123456:@github.com
要为给定git主机上的特定存储库使用不同的凭据,您可以将存储库路径(即<repo>
)附加到条目中,以使匹配更加严格。(存储库路径中的.git
文件扩展名是可选的)。
https://<凭据>@<主机名>/<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
在URL中指定存储库路径是可选的。如果不包含它,该凭据对所有共享相同git主机的URL都将使用。 |
根据您为内容源使用的URL格式以及是否在playbook中配置了ensure_git_suffix键,您可能需要附加.git 文件扩展名。 |
请注意,令牌根据git主机的不同位置位于URL中的不同位置。有关更多详细信息,请参阅OAuth2格式。如果使用Bitbucket应用密码,请注意您必须包含自己的用户名(使用格式USERNAME:APP_PASSWORD )。 |
为确保凭据文件受到保护,请立即设置其文件权限,以防止他人读取。
$ chmod 600 $HOME/.git-credentials
指定自定义的git凭据存储路径
您可以指示Antora在不同位置查找文件,而不是使用默认路径中的凭据存储,方法是使用--git-credentials-path
CLI选项或GIT_CREDENTIALS_PATH
环境变量,两者都在运行时设置git.credentials.path
playbook键。
以下是一个示例,使用CLI选项指定相对于playbook文件的路径:
$ antora --git-credentials-path=./.git-credentials antora-playbook.yml
要了解如何使用git.credentials.path
playbook键的更多信息,包括如何直接在playbook中设置它,请参阅git.credentials.path键的参考文档。
通过环境变量传递凭据
您可以让Antora直接从名为GIT_CREDENTIALS
的环境变量中读取凭据,该环境变量在运行时设置git.credentials.contents
playbook键。
以下是演示该概念的示例:
$ 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时都输入它。
要了解如何使用git.credentials.contents
playbook键的更多信息,包括如何直接在playbook中设置它,请参阅git.credentials.contents键的参考文档。
在URL中编码凭据(不推荐)
将凭据传递给凭据管理器的另一种选项是直接在playbook中列出的URL中对其进行编码。由于此选项不会触发挑战-响应工作流程,Antora会自动假定存储库是私有的。
除非您使用占位符来注入真实凭据(如本节末尾所述),否则不建议使用此策略。 |
如果服务器要求,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
请注意,令牌位于URL中的不同位置,具体取决于git主机。有关更多详细信息,请参阅OAuth2格式。如果使用Bitbucket应用密码,请注意必须包含您自己的用户名(使用格式USERNAME:APP_PASSWORD )。 |
这种方法的缺点是需要直接将凭据放入playbook文件中。不幸的是,Antora目前尚不支持解析playbook文件中的环境变量。但是,您可以通过使用脚本来替换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 }
数据对象。当凭据被服务器批准或拒绝时,将调用approved
和rejected
方法。
可选的configure
和status
方法是Antora特有的,扩展了isomorphic-git中凭据管理器通常提供的功能。如果定义了configure
方法,Antora每次启动时都会调用它,提供执行初始化步骤的机会,比如定义属性。如果有status
方法,则Antora将使用它来查找给定URL是否请求了身份验证。
要激活您的自定义凭据管理器,首先在一个专用的JavaScript文件中编写您的实现,并将其配置为默认导出:
module.exports = {
async fill ({ url }) { ... },
async approved ({ url }) { ... },
async rejected ({ url, auth }) { ... },
}
然后按以下方式将凭据管理器注册到playbook中:
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构建器会自动为我们驼峰化键名,这是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(即将Antora包添加到package.json文件的依赖项中,并运行npm i
)。
由于自注册插件更为复杂,我们将继续使用在playbook中注册插件的示例。
从git获取凭据
Git提供了一个名为git credential
的命令,它作为一个简单的接口,以与git本身相同的方式存储和检索凭据,也可以提示用户输入用户名和密码。我们可以在自定义凭据管理器中使用此命令,允许Antora委托给git查找凭据(从而与用户自己的git设置集成)。
让我们首先创建一个辅助函数,通过git credentials 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]
},
}
最后,我们需要在playbook中注册凭据管理器:
git:
plugins:
credential_manager: ./system-git-credential-manager.js
现在Antora将委托给系统git填充URL的凭据:
$ antora antora-playbook.yml
读者可以根据服务器批准或拒绝凭据的情况存储或删除凭据(提示:使用approved
和rejected
方法再次调用git credential
)。