我如何使用 gRPC 为 google 云 运行 设置 jwcrypto 令牌发行者?
How would I setup a jwcrypto token issuer for google cloud run with gRPC?
我正在尝试为 Google 云端点创建自定义身份验证方法。这个想法是我可以配置我的 ESPv2 容器(基于 Envoy 的可扩展服务代理),它托管在 Google 云 运行 上,从自定义发行者那里获取 JWT,也托管在云 [=36] 上=].
按照指南 Endpoints guide for gRPC,我认为 yaml 文件的 jwks_uri:
部分应该指向一个 URL,它暴露了 public 键(我认为你可以通过将 JWK 放入 json 文件并将所述 JSON 文件托管在 google 云存储上,将其公开到 public 互联网来实现。
让我难过的部分是发行者,我已经完成了 RFC7519,它指出发行者是一个字符串或 URI 值。我不太熟悉 ESPv2 容器使用的 Envoy 的具体实现,但我最好的猜测是 yaml 文件中的 issuer:
选项只是用于匹配从服务器发出的域或字符串创建令牌时。
我可能是错的,所以非常感谢您提供有关这方面的指导。
亲切的问候,
卑鄙B
issuer 应该是您发送到 ESPv2 的 JWT 令牌中的 "iss" 字段。
作者的解决方案
在与 Google 云端点团队以及 ESPv2 的一些贡献者合作后,我们弄明白了这一点(并发现了一些要指出给将来想要这样做的人的一些事情) .
解决原始问题
事实上,正如 Wayne Zhang 所指出的,发行者可以是任何字符串值,只要它与 JWT 负载中的“iss”声明匹配即可。
例如
authentication:
providers:
- id: some-fancy-id
issuer: fart # <-- Don't wrapping ANY these in double-quotes
jwks_uri: https://storage.googleapis.com/your-public-bucket/jwk-public-key.json
audiences: some-specific-name
然后在你的(解码的)JWT
// Header
{
"alg": "RS256",
"kid": "custom-id-system-you-specify",
"typ": "JWT"
}
// Payload
{
"aud": [
"some-specific-name"
],
"exp": 1590139950, <-- MUST be INTEGER value
"iat": 1590136350, <-- ^^
"iss": "fart",
"sub": "Here is some sulphur dioxide"
}
Error/Bug #1 - “iat”和“exp”应该是整数而不是字符串
正如您已经从上面解码的 JWT 中看到的那样,“exp”和“iat”声明必须是整数值(这可以在 RFC7519 4.1.4 和 4.1.6 节中清楚地看到).
这似乎是一个简单的错误,但正如 ESPv2 贡献者和我发现的那样,错误消息在帮助开发人员找出问题所在方面并不是特别有用。
例如,如果您将“iat”和“exp”声明写成字符串而不是整数,ESPv2 容器会通知开发者他的 JWT 不是正确的 Base64URL 格式,就是无效 JSON。在不知情的情况下,您可能会认为您错误地使用了该库。
为了将来解决这个问题,对错误消息进行了一些更改,您可以看到提出的问题及其结论 here。
错误 #2 - 密钥错误,JSON 格式
在宣布这场消耗战的胜利之前,我 运行 又犯了一个错误,这个错误和之前的一样模糊。
当尝试调用需要身份验证的方法时,我遇到了以下问题
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAUTHENTICATED
details = "Jwks remote fetch is failed"
debug_error_string = "{"created":"@1590054504.221608572","description":"Error received from peer ipv4:216.239.36.53:443","file":"src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Jwks remote fetch is failed","grpc_status":16}"
>
您可能认为这意味着 ESPv2 无法检索您的密钥。
原因是三个相关问题。
ESPv2 只支持 X509 和 RSA 密钥对,所以不要重蹈我的覆辙,使用 EC 生成的密钥对。
jwcrypto 默认情况下不会将“alg”和“kid”声明添加到您的密钥文件中,请确保添加了这些声明,否则 jwcrypto 将不知道在签署任何 JWT 时使用什么算法已生成。
最后的错误是JSON文件的格式。当您调用导出密钥的方法时,您会得到以下信息:
{
"e":"XXXX",
"kty":"RSA",
"n":"crazyRandomNumbersAndLetters",
"alg": "RS256", <-- NOT ADDED BY DEFAULT
"kid": "custom-id-system-you-specify" <-- ^^
}
在 JSON 文件中简单地为此提供 URL 是不正确的。正确格式如下:
{
"keys": [
{
"e":"XXXX",
"kty":"RSA",
"n":"crazyRandomNumbersAndLetters",
"alg": "RS256", <-- NOT ADDED BY DEFAULT
"kid": "custom-id-system-you-specify" <-- ^^
}
]
}
如果你做到了这一切,应该会一帆风顺。
我很抱歉有点跑题了,但我希望其他人不必像我一样经历那么多困难才能实现这一目标:)
我非常感谢 ESPv2 的开发人员,感谢他们的快速回复和对问题的洞察力。干得好!
祝编码顺利!
- 卑鄙小B.
我正在尝试为 Google 云端点创建自定义身份验证方法。这个想法是我可以配置我的 ESPv2 容器(基于 Envoy 的可扩展服务代理),它托管在 Google 云 运行 上,从自定义发行者那里获取 JWT,也托管在云 [=36] 上=].
按照指南 Endpoints guide for gRPC,我认为 yaml 文件的 jwks_uri:
部分应该指向一个 URL,它暴露了 public 键(我认为你可以通过将 JWK 放入 json 文件并将所述 JSON 文件托管在 google 云存储上,将其公开到 public 互联网来实现。
让我难过的部分是发行者,我已经完成了 RFC7519,它指出发行者是一个字符串或 URI 值。我不太熟悉 ESPv2 容器使用的 Envoy 的具体实现,但我最好的猜测是 yaml 文件中的 issuer:
选项只是用于匹配从服务器发出的域或字符串创建令牌时。
我可能是错的,所以非常感谢您提供有关这方面的指导。
亲切的问候,
卑鄙B
issuer 应该是您发送到 ESPv2 的 JWT 令牌中的 "iss" 字段。
作者的解决方案
在与 Google 云端点团队以及 ESPv2 的一些贡献者合作后,我们弄明白了这一点(并发现了一些要指出给将来想要这样做的人的一些事情) .
解决原始问题
事实上,正如 Wayne Zhang 所指出的,发行者可以是任何字符串值,只要它与 JWT 负载中的“iss”声明匹配即可。
例如
authentication:
providers:
- id: some-fancy-id
issuer: fart # <-- Don't wrapping ANY these in double-quotes
jwks_uri: https://storage.googleapis.com/your-public-bucket/jwk-public-key.json
audiences: some-specific-name
然后在你的(解码的)JWT
// Header
{
"alg": "RS256",
"kid": "custom-id-system-you-specify",
"typ": "JWT"
}
// Payload
{
"aud": [
"some-specific-name"
],
"exp": 1590139950, <-- MUST be INTEGER value
"iat": 1590136350, <-- ^^
"iss": "fart",
"sub": "Here is some sulphur dioxide"
}
Error/Bug #1 - “iat”和“exp”应该是整数而不是字符串
正如您已经从上面解码的 JWT 中看到的那样,“exp”和“iat”声明必须是整数值(这可以在 RFC7519 4.1.4 和 4.1.6 节中清楚地看到).
这似乎是一个简单的错误,但正如 ESPv2 贡献者和我发现的那样,错误消息在帮助开发人员找出问题所在方面并不是特别有用。
例如,如果您将“iat”和“exp”声明写成字符串而不是整数,ESPv2 容器会通知开发者他的 JWT 不是正确的 Base64URL 格式,就是无效 JSON。在不知情的情况下,您可能会认为您错误地使用了该库。
为了将来解决这个问题,对错误消息进行了一些更改,您可以看到提出的问题及其结论 here。
错误 #2 - 密钥错误,JSON 格式
在宣布这场消耗战的胜利之前,我 运行 又犯了一个错误,这个错误和之前的一样模糊。
当尝试调用需要身份验证的方法时,我遇到了以下问题
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAUTHENTICATED
details = "Jwks remote fetch is failed"
debug_error_string = "{"created":"@1590054504.221608572","description":"Error received from peer ipv4:216.239.36.53:443","file":"src/core/lib/surface/call.cc","file_line":1056,"grpc_message":"Jwks remote fetch is failed","grpc_status":16}"
>
您可能认为这意味着 ESPv2 无法检索您的密钥。 原因是三个相关问题。
ESPv2 只支持 X509 和 RSA 密钥对,所以不要重蹈我的覆辙,使用 EC 生成的密钥对。
jwcrypto 默认情况下不会将“alg”和“kid”声明添加到您的密钥文件中,请确保添加了这些声明,否则 jwcrypto 将不知道在签署任何 JWT 时使用什么算法已生成。
最后的错误是JSON文件的格式。当您调用导出密钥的方法时,您会得到以下信息:
{ "e":"XXXX", "kty":"RSA", "n":"crazyRandomNumbersAndLetters", "alg": "RS256", <-- NOT ADDED BY DEFAULT "kid": "custom-id-system-you-specify" <-- ^^ }
在 JSON 文件中简单地为此提供 URL 是不正确的。正确格式如下:
{
"keys": [
{
"e":"XXXX",
"kty":"RSA",
"n":"crazyRandomNumbersAndLetters",
"alg": "RS256", <-- NOT ADDED BY DEFAULT
"kid": "custom-id-system-you-specify" <-- ^^
}
]
}
如果你做到了这一切,应该会一帆风顺。
我很抱歉有点跑题了,但我希望其他人不必像我一样经历那么多困难才能实现这一目标:)
我非常感谢 ESPv2 的开发人员,感谢他们的快速回复和对问题的洞察力。干得好!
祝编码顺利!
- 卑鄙小B.