在使用极狐GitLab 令牌时,您可能会遇到以下问题。
过期的访问令牌
如果现有的访问令牌正在使用中并达到了 expires_at
的值,令牌会过期,并且:
- 无法再用于身份验证。
- 在用户界面中不可见。
使用此令牌进行的请求将返回 401 Unauthorized
响应。来自同一 IP 地址在短时间内发送的过多未经授权的请求,将导致 JihuLab.com 返回 403 Forbidden
响应。
有关身份验证请求限制的更多信息,请参阅 Git 和容器注册表身份验证失败禁令。
从日志中识别过期的访问令牌
{{< history >}}
- 在极狐GitLab 17.2 中引入。
{{< /history >}}
前提条件:
您必须:
- 是一名管理员。
- 具有访问
api_json.log
文件的权限。
要识别由于过期的访问令牌而导致失败的 401 Unauthorized
请求,请使用 api_json.log
文件中的以下字段:
字段名称 | 描述 |
---|---|
meta.auth_fail_reason |
请求被拒绝的原因。可能的值:token_expired 、token_revoked 、insufficient_scope 和 impersonation_disabled 。 |
meta.auth_fail_token_id |
描述尝试使用的令牌类型和 ID 的字符串。 |
当用户尝试使用过期的令牌时,meta.auth_fail_reason
是 token_expired
。以下是日志条目的摘录:
{
"status": 401,
"method": "GET",
"path": "/api/v4/user",
...
"meta.auth_fail_reason": "token_expired",
"meta.auth_fail_token_id": "PersonalAccessToken/12",
}
meta.auth_fail_token_id
表示使用了 ID 为 12 的访问令牌。
要查找有关此令牌的更多信息,请使用 个人访问令牌 API。您还可以使用 API 旋转令牌。
替换过期的访问令牌
要替换令牌:
- 检查此令牌可能以前使用过的位置,并将其从任何可能仍在使用该令牌的自动化中移除。
- 对于个人访问令牌,使用 API 列出最近过期的令牌。例如,转到
https://jihulab.com/api/v4/personal_access_tokens
,并找到具有特定expires_at
日期的令牌。 - 对于项目访问令牌,使用 项目访问令牌 API 列出最近过期的令牌。
- 对于群组访问令牌,使用 群组访问令牌 API 列出最近过期的令牌。
- 对于个人访问令牌,使用 API 列出最近过期的令牌。例如,转到
- 创建一个新的访问令牌:
- 对于个人访问令牌,使用用户界面 或 用户令牌 API。
- 对于项目访问令牌,使用用户界面 或 项目访问令牌 API。
- 对于群组访问令牌,使用用户界面 或 群组访问令牌 API。
- 用新访问令牌替换旧访问令牌。此过程因您如何使用令牌而异,例如如果配置为密钥或嵌入应用程序中。从该令牌发出的请求不应再返回
401
响应。
延长令牌的有效期
使用此脚本延迟某些令牌的过期时间。
从极狐GitLab 16.0 开始,所有访问令牌都有一个到期日期。在您部署至少极狐GitLab 16.0 后,任何没有过期的访问令牌将在部署日期一年后过期。
如果这个日期临近,并且有尚未旋转的令牌,您可以使用此脚本来延迟过期,给用户更多时间来旋转他们的令牌。
为特定令牌延长有效期
此脚本延长在指定日期到期的所有令牌的有效期,包括:
- 个人访问令牌
- 群组访问令牌
- 项目访问令牌
对于群组和项目访问令牌,此脚本仅在升级到极狐GitLab 16.0 或更高版本时自动设置了过期日期的情况下延长这些令牌的有效期。如果群组或项目访问令牌是在生成时设置了过期日期,或已旋转,则该令牌的有效性取决于对资源的有效成员资格,因此无法使用此脚本延长令牌的有效期。
要使用此脚本:
{{< tabs >}}
{{< tab title=”Rails console session” >}}
- 在终端窗口中,使用
sudo gitlab-rails console
启动一个 Rails 控制台会话。 - 粘贴下面整个
extend_expiring_tokens.rb
脚本。如果需要,将expiring_date
更改为其他日期。 - 按 Enter。
{{< /tab >}}
{{< tab title=”Rails Runner” >}}
- 在终端窗口中,连接到您的实例。
- 复制下面整个
extend_expiring_tokens.rb
脚本,并将其保存为实例上的一个文件:- 命名为
extend_expiring_tokens.rb
。 - 如果需要,将
expiring_date
更改为其他日期。 - 文件必须对
git:git
可访问。
- 命名为
-
运行此命令,将
/path/to/extend_expiring_tokens.rb
更改为extend_expiring_tokens.rb
文件的完整路径:sudo gitlab-rails runner /path/to/extend_expiring_tokens.rb
有关更多信息,请参阅 Rails Runner 故障排除部分。
{{< /tab >}}
{{< /tabs >}}
extend_expiring_tokens.rb
expiring_date = Date.new(2024, 5, 30)
new_expires_at = 6.months.from_now
total_updated = PersonalAccessToken
.not_revoked
.without_impersonation
.where(expires_at: expiring_date.to_date)
.update_all(expires_at: new_expires_at.to_date)
puts "Updated #{total_updated} tokens with new expiry date #{new_expires_at}"
识别在特定日期到期的个人、项目和群组访问令牌
没有到期日期的访问令牌无限期有效,如果访问令牌被泄露,这将是一个安全风险。
为了管理此风险,当您升级到极狐GitLab 16.0 及更高版本时,任何没有到期日期的个人、项目或群组访问令牌将自动设置为自升级日期起一年后的到期日期。
在极狐GitLab 17.3 及更高版本中,此现有令牌到期的自动设置已被恢复,您可以禁用新访问令牌的到期日期强制执行。
如果您不知道您的令牌何时到期,因为日期已更改,那么在尝试在该日期登录极狐GitLab 时,您可能会遇到意外的身份验证失败。
为了解决此问题,您应升级到极狐GitLab 17.2 或更高版本,因为这些版本包含一个工具,帮助分析、延长或删除令牌过期日期。
如果您无法运行该工具,您还可以在极狐GitLab 私有化部署实例中运行脚本,以识别以下任一类型的令牌:
- 在特定日期到期。
- 没有到期日期。
您可以通过以下任一方式从终端窗口运行这些脚本:
- Rails 控制台会话。
- 使用 Rails Runner。
根据您是否已升级到极狐GitLab 16.0 及更高版本,您运行的具体脚本有所不同:
- 如果您尚未升级到极狐GitLab 16.0 或更高版本,请识别没有到期日期的令牌。
- 如果您已升级到极狐GitLab 16.0 或更高版本,请使用脚本识别以下任一类型的令牌:
在识别出受此问题影响的令牌后,如果需要,您可以运行最终脚本来延长特定令牌的有效期。
这些脚本返回的结果格式如下:
Expired group access token in Group ID 25, Token ID: 8, Name: Example Token, Scopes: ["read_api", "create_runner"], Last used:
Expired project access token in Project ID 2, Token ID: 9, Name: Test Token, Scopes: ["api", "read_registry", "write_registry"], Last used: 2022-02-11 13:22:14 UTC
查找在特定日期到期的所有令牌
此脚本查找在特定日期到期的令牌。
前提条件:
- 您必须知道您的实例升级到极狐GitLab 16.0 的确切日期。
使用方法:
{{< tabs >}}
{{< tab title=”Rails console session” >}}
- 在终端窗口中,连接到您的实例。
- 使用
sudo gitlab-rails console
启动一个 Rails 控制台会话。 - 根据需要,复制下面整个
expired_tokens.rb
或expired_tokens_date_range.rb
脚本,并将其粘贴到控制台中。将expires_at_date
更改为您的实例升级到极狐GitLab 16.0 一年后的日期。 - 按 Enter。
{{< /tab >}}
{{< tab title=”Rails Runner” >}}
- 在终端窗口中,连接到您的实例。
- 根据需要,复制下面整个
expired_tokens.rb
或expired_tokens_date_range.rb
脚本,并将其保存为实例上的一个文件:- 命名为
expired_tokens.rb
。 - 将
expires_at_date
更改为您的实例升级到极狐GitLab 16.0 一年后的日期。 - 文件必须对
git:git
可访问。
- 命名为
-
运行此命令,将路径更改为
expired_tokens.rb
文件的完整路径:sudo gitlab-rails runner /path/to/expired_tokens.rb
有关更多信息,请参阅 Rails Runner 故障排除部分。
{{< /tab >}}
{{< /tabs >}}
expired_tokens.rb
此脚本要求您知道极狐GitLab 实例升级到极狐GitLab 16.0 的确切日期。
# 将此值更改为您的极狐GitLab 实例升级一年后的日期。
expires_at_date = "2024-05-22"
# 检查即将到期的个人访问令牌
PersonalAccessToken.owner_is_human.where(expires_at: expires_at_date).find_each do |token|
if token.user.blocked?
next
# 从输出中隐藏不可用的被阻止的个人访问令牌
end
puts "Expired personal access token ID: #{token.id}, User Email: #{token.user.email}, Name: #{token.name}, Scopes: #{token.scopes}, Last used: #{token.last_used_at}"
end
# 检查即将到期的项目和群组访问令牌
PersonalAccessToken.project_access_token.where(expires_at: expires_at_date).find_each do |token|
token.user.members.each do |member|
type = member.is_a?(GroupMember) ? 'Group' : 'Project'
puts "Expired #{type} access token in #{type} ID #{member.source_id}, Token ID: #{token.id}, Name: #{token.name}, Scopes: #{token.scopes}, Last used: #{token.last_used_at}"
end
end
{{< alert type=”note” >}}
如果不仅要隐藏,还要移除属于被阻止用户的令牌,请在 if token.user.blocked?
下面直接添加 token.destroy!
。但是,与 API 方法 不同,此操作不会留下审计事件。
{{< /alert >}}
查找在特定月份到期的令牌
此脚本查找在特定月份到期的令牌。您无需知道实例升级到极狐GitLab 16.0 的确切日期。使用方法:
{{< tabs >}}
{{< tab title=”Rails console session” >}}
- 在终端窗口中,使用
sudo gitlab-rails console
启动一个 Rails 控制台会话。 - 粘贴下面整个
tokens_with_no_expiry.rb
脚本。如果需要,将date_range
更改为其他范围。 - 按 Enter。
{{< /tab >}}
{{< tab title=”Rails Runner” >}}
- 在终端窗口中,连接到您的实例。
- 复制下面整个
tokens_with_no_expiry.rb
脚本,并将其保存为实例上的一个文件:- 命名为
expired_tokens_date_range.rb
。 - 如果需要,将
date_range
更改为其他范围。 - 文件必须对
git:git
可访问。
- 命名为
-
运行此命令,将
/path/to/expired_tokens_date_range.rb
更改为expired_tokens_date_range.rb
文件的完整路径:sudo gitlab-rails runner /path/to/expired_tokens_date_range.rb
有关更多信息,请参阅 Rails Runner 故障排除部分。
{{< /tab >}}
{{< /tabs >}}
expired_tokens_date_range.rb
# 此脚本允许您在当前日期起的特定日期范围内(例如 1 个月)搜索令牌。如果您不确定极狐GitLab 16.0 的升级确切完成时间,请使用它。
date_range = 1.month
# 检查个人访问令牌
PersonalAccessToken.owner_is_human.where(expires_at: Date.today .. Date.today + date_range).find_each do |token|
puts "Expired personal access token ID: #{token.id}, User Email: #{token.user.email}, Name: #{token.name}, Scopes: #{token.scopes}, Last used: #{token.last_used_at}"
end
# 检查即将到期的项目和群组访问令牌
PersonalAccessToken.project_access_token.where(expires_at: Date.today .. Date.today + date_range).find_each do |token|
token.user.members.each do |member|
type = member.is_a?(GroupMember) ? 'Group' : 'Project'
puts "Expired #{type} access token in #{type} ID #{member.source_id}, Token ID: #{token.id}, Name: #{token.name}, Scopes: #{token.scopes}, Last used: #{token.last_used_at}"
end
end
识别许多令牌到期的日期
此脚本识别大多数令牌到期的日期。您可以将其与本页上的其他脚本结合使用,以识别和扩展可能接近到期日期的大批量令牌,以防您的团队尚未设置令牌轮换。
该脚本返回的结果格式如下:
42 Personal access tokens will expire at 2024-06-27
17 Personal access tokens will expire at 2024-09-23
3 Personal access tokens will expire at 2024-08-13
使用方法:
{{< tabs >}}
{{< tab title=”Rails console session” >}}
- 在终端窗口中,使用
sudo gitlab-rails console
启动一个 Rails 控制台会话。 - 粘贴整个
dates_when_most_of_tokens_expire.rb
脚本。 - 按 Enter。
{{< /tab >}}
{{< tab title=”Rails Runner” >}}
- 在终端窗口中,连接到您的实例。
- 复制整个
dates_when_most_of_tokens_expire.rb
脚本,并将其保存为实例上的一个文件:- 命名为
dates_when_most_of_tokens_expire.rb
。 - 文件必须对
git:git
可访问。
- 命名为
-
运行此命令,将
/path/to/dates_when_most_of_tokens_expire.rb
更改为dates_when_most_of_tokens_expire.rb
文件的完整路径:sudo gitlab-rails runner /path/to/dates_when_most_of_tokens_expire.rb
有关更多信息,请参阅 Rails Runner 故障排除部分。
{{< /tab >}}
{{< /tabs >}}
dates_when_most_of_tokens_expire.rb
PersonalAccessToken
.select(:expires_at, Arel.sql('count(*)'))
.where('expires_at >= NOW()')
.group(:expires_at)
.order(Arel.sql('count(*) DESC'))
.limit(10)
.each do |token|
puts "#{token.count} Personal access tokens will expire at #{token.expires_at}"
end
查找没有到期日期的令牌
此脚本查找缺少到期日期的令牌:expires_at
为 NULL
。对于尚未升级到极狐GitLab 16.0 或更高版本的用户,令牌的 expires_at
值为 NULL
,可以用于识别需要添加到期日期的令牌。
您可以在 Rails 控制台 或 Rails Runner 中使用此脚本:
{{< tabs >}}
{{< tab title=”Rails console session” >}}
- 在终端窗口中,连接到您的实例。
- 使用
sudo gitlab-rails console
启动一个 Rails 控制台会话。 - 粘贴下面整个
tokens_with_no_expiry.rb
脚本。 - 按 Enter。
{{< /tab >}}
{{< tab title=”Rails Runner” >}}
- 在终端窗口中,连接到您的实例。
- 复制下面整个
tokens_with_no_expiry.rb
脚本,并将其保存为实例上的一个文件:- 命名为
tokens_with_no_expiry.rb
。 - 文件必须对
git:git
可访问。
- 命名为
-
运行此命令,将路径更改为
tokens_with_no_expiry.rb
文件的完整路径:sudo gitlab-rails runner /path/to/tokens_with_no_expiry.rb
有关更多信息,请参阅 Rails Runner 故障排除部分。
{{< /tab >}}
{{< /tabs >}}
tokens_with_no_expiry.rb
此脚本查找没有设置 expires_at
值的令牌。
# 此脚本查找没有设置 expires_at 值的令牌。
# 检查个人访问令牌
PersonalAccessToken.owner_is_human.where(expires_at: nil).find_each do |token|
puts "Expires_at is nil for personal access token ID: #{token.id}, User Email: #{token.user.email}, Name: #{token.name}, Scopes: #{token.scopes}, Last used: #{token.last_used_at}"
end
# 检查即将到期的项目和群组访问令牌
PersonalAccessToken.project_access_token.where(expires_at: nil).find_each do |token|
token.user.members.each do |member|
type = member.is_a?(GroupMember) ? 'Group' : 'Project'
puts "Expires_at is nil for #{type} access token in #{type} ID #{member.source_id}, Token ID: #{token.id}, Name: #{token.name}, Scopes: #{token.scopes}, Last used: #{token.last_used_at}"
end
end