获取 rfc7517 格式的 JWKS for Firebase
Getting JWKS for Firebase in rfc7517 format
我正在使用 Firebase 对我的应用程序中的用户进行身份验证。 Firebase 生成一个我需要在我的服务器上进行身份验证的 JWT 令牌。我使用 tyk.io 来做到这一点。 Tyk 支持这些标记,但要求 public 键的数据源采用 https://www.rfc-editor.org/rfc/rfc7517 格式。
有直接从 Google/Firebase 获取这个的简单方法吗?
我知道我可以从 https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com 获取密钥,但这不是预期的格式。
我还可以从 https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com 获取 jwk,这是正确的格式但不包含密钥(我需要 X5c 字段中的密钥,所以 X.509 证书链)
正如您在阅读 Tyk library on GitHub 时注意到的那样,Tyk 已选择仅支持 JWK 集中在证书中发布的 RSA 密钥。
初步说明:
Google 用于签署 JSON Web 令牌的 RSA 密钥是在 https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
发布的两个密钥之一
那两个密钥是用来在https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com
制作两个证书的密钥
注意这些证书是自签名的,这里是其中一个的内容:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4804715264884888226 (0x42adc713b25c52a2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=securetoken.system.gserviceaccount.com
Validity
Not Before: Apr 2 21:20:50 2019 GMT
Not After : Apr 19 09:35:50 2019 GMT
Subject: CN=securetoken.system.gserviceaccount.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cc:7c:14:e6:5c:95:94:4b:95:74:0d:47:9d:e1:
[...]
60:d1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage: critical
TLS Web Client Authentication
Signature Algorithm: sha1WithRSAEncryption
[...]
如您所见,颁发者与主题具有相同的价值,因此证书链由单个自签名证书组成。这意味着您无法使用证书颁发机构检查此证书的有效性:没有全球知名的证书颁发机构签署来自 Google 的 public RSA 密钥来制作这些证书。但是证书是通过 SSL/TLS 从 Google Web 服务器下载的,该服务器使用由 GlobalSign 签名的证书进行身份验证,因此使用 SSL/TLS 下载证书足以确保那些证书包含 Google 用于签署 JWT 的 RSA 密钥。
证书仅在几周内有效,并且具有重叠的验证期以避免时钟偏差,并且几乎每两周应用一次滚动密钥机制。
您问题的答案:
您需要自己创建 public-key 源以便 Google 与 Tyk 一起工作:您必须在包含 JWK 集的应用程序服务器上创建一个文档。我们假设您在此处发布此 JWK 集:https://my-application-server.com/jwks.json
所以,在你的 Tyk API 定义中,在 JWT 秘密字段中,你需要把这个 JWK 集合 URL: https://my-application-server.com/jwks.json.
为此,请参阅此页面中有关 JWT 秘密字段 的部分:https://community.tyk.io/t/multiple-auth-schemes-for-single-api-definition/694/4
您需要每周刷新此文档,因为 Google 大约每两周滚动一次密钥。
可以使用以下 shell 命令制作此文档,仅使用 curl 和名为 jq: 的 JSON 命令行处理器
curl -s 'https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com' | jq '[ to_entries | .[] | {alg: "RS256", kty: "RSA", use: "sig", kid: .key, x5c: (.value | sub(".*"; "") | sub("\n"; ""; "g") | sub("-.*"; "")) } ] | {"keys": .}'
这是此命令行的输出:
% curl -s 'https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com' | jq '[ to_entries | .[] | {alg: "RS256", kty: "RSA", use: "sig", kid: .key, x5c: (.value | sub(".*"; "") | sub("\n"; ""; "g") | sub("-.*"; "")) } ] | {"keys": .}'
{
"keys": [
{
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"kid": "7d2f9f3fb83d6337497b6f7cd2cff4dfa5c2e8b8",
"x5c": "MIIDHDCCAgSgAwIBAgIIQq3HE7JcUqIwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UEAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTkwNDAyMjEyMDUwWhcNMTkwNDE5MDkzNTUwWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tlbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMx8FOZclZRLlXQNR53h+mYYjo9X4Hi38dAsLrP2iRzt8PowOnqx7hxpr9Ag7NKTSAOXTUAmObCRkEooRLe6jcScu+nttpjqqvtOyzhTl2szbdsiRhveXmOwMMbZ/DCkXll6i2NoeeRxVy4qxMDMPM6pokjsUyuq9wkWH+fiUG8rYSZVhpCqfOtqoTBu0zf+PyuGDPlLKKkE6Y7WKp5Go/tIMS6kTz5vhnA3M0HNWdZDy+06kT0eTxajzcs/QXiqmMzJEsJ7ln0Qh1KnOZwMH578y9GYM3ytMdiybDQM0c4cWtLp0REjlKyzqh0LLA7fmdjmEmIgOSy1wzftcKnfYNECAwEAAaM4MDYwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADggEBAFpLrULiau0nFLjRXxt9lwjgft1elBt265Hu88TU3132Wbh00Yvm7hlOA34gVIVNPcgT5lCxc4qVLXbA6yPtnyDubvULmVxyCSKfX/2M4Td+yPF99xR3VVCpATPAVjtOo819Q/Of+icQlmSoy/I0lFJewwrqcRc0eC9UgzF+EvGXHzIfoNlQgFjf/fnG1OV7d2Zr8bj+Jk/zZwVRstKCTrPgyqCYe/y7PU9q0aIQnMRvYKdLj/TfaBolQ12Tlb2j+nGMrPH5uVsUUu6nZluhaMvmlhp8glvslmjlXCIuce/N8FSw7zVf/ofRrDzTw98N1DZG2aLRyRYdmsXDBqMaac8="
},
{
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"kid": "ff1df5a15b5cf582b61a21385c0cfaedfdb6a748",
"x5c": "MIIDHDCCAgSgAwIBAgIIcqcNMyhOv18wDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UEAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTkwMzI1MjEyMDUwWhcNMTkwNDExMDkzNTUwWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tlbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKnDRgOsHY55P2i7wX6Uh8YO/rBWmGgVgeBqCowbHopF5HA1EdF0NXSmBn1Myg+DLFqxf0nvsi8B5pjd/rNtVPX6OUIkAKGPyva/d2aQqsHliCFh81QDs2vHIeIAThbQZP514t/z2M79SWR7A0vRYcWf+I+eTL6Vf1nqO3cFwTJVtwiTPom+NjZKx7ukowtqm1mVef+FqceC5zx8D5wzLLtUx/tMPvnXaysSjNN+86cPKc02kumCqlt7Yuf5G9VptjAVqsQyL/X5WuIVuzkFrfh/IPidw7Wzm3s5u928aLNSNbFpEpeXqJ8utD4AZnfm9mg6PYNtFWIB/L6xf21iZOECAwEAAaM4MDYwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADggEBAEdXAGI27mRT+Qkz9vbGlGbKJZKLG6b6c/SAQkOZJDOX4sJ16WgbfsixGBEWmvMMiEwhWV0hbhTiEC22xUd7cRP6veRlKba4rKoYA0x3GJhpDpAviuKPFkCanLFlFOXouexQIxBudWm32B8YFpLW9ds8m9yFmQZwE5GZs1hJ1jb2z2u7AuZNdQnaQ7mKy7Vmt3yHb9NjPlvmQ//ijFR3Lw4XB3nlYcL77mjjd3fhBodfUFkPJpsY2wOQpRLxDbvjHsXSfsgQ+/a+9IjKj0F2YOu9HnvjTXCopWObA9AGV6HR2L6RGaRLTwH+xV2El8UrzTYFPPN/URLui3XtaGdiREg="
}
]
}
这个输出的内容必须保存在https://my-application-server.com/jwks.json
对应的文件中
我正在使用 Firebase 对我的应用程序中的用户进行身份验证。 Firebase 生成一个我需要在我的服务器上进行身份验证的 JWT 令牌。我使用 tyk.io 来做到这一点。 Tyk 支持这些标记,但要求 public 键的数据源采用 https://www.rfc-editor.org/rfc/rfc7517 格式。
有直接从 Google/Firebase 获取这个的简单方法吗?
我知道我可以从 https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com 获取密钥,但这不是预期的格式。
我还可以从 https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com 获取 jwk,这是正确的格式但不包含密钥(我需要 X5c 字段中的密钥,所以 X.509 证书链)
正如您在阅读 Tyk library on GitHub 时注意到的那样,Tyk 已选择仅支持 JWK 集中在证书中发布的 RSA 密钥。
初步说明:
Google 用于签署 JSON Web 令牌的 RSA 密钥是在 https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
发布的两个密钥之一那两个密钥是用来在https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com
制作两个证书的密钥注意这些证书是自签名的,这里是其中一个的内容:
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 4804715264884888226 (0x42adc713b25c52a2)
Signature Algorithm: sha1WithRSAEncryption
Issuer: CN=securetoken.system.gserviceaccount.com
Validity
Not Before: Apr 2 21:20:50 2019 GMT
Not After : Apr 19 09:35:50 2019 GMT
Subject: CN=securetoken.system.gserviceaccount.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cc:7c:14:e6:5c:95:94:4b:95:74:0d:47:9d:e1:
[...]
60:d1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage: critical
TLS Web Client Authentication
Signature Algorithm: sha1WithRSAEncryption
[...]
如您所见,颁发者与主题具有相同的价值,因此证书链由单个自签名证书组成。这意味着您无法使用证书颁发机构检查此证书的有效性:没有全球知名的证书颁发机构签署来自 Google 的 public RSA 密钥来制作这些证书。但是证书是通过 SSL/TLS 从 Google Web 服务器下载的,该服务器使用由 GlobalSign 签名的证书进行身份验证,因此使用 SSL/TLS 下载证书足以确保那些证书包含 Google 用于签署 JWT 的 RSA 密钥。
证书仅在几周内有效,并且具有重叠的验证期以避免时钟偏差,并且几乎每两周应用一次滚动密钥机制。
您问题的答案:
您需要自己创建 public-key 源以便 Google 与 Tyk 一起工作:您必须在包含 JWK 集的应用程序服务器上创建一个文档。我们假设您在此处发布此 JWK 集:https://my-application-server.com/jwks.json
所以,在你的 Tyk API 定义中,在 JWT 秘密字段中,你需要把这个 JWK 集合 URL: https://my-application-server.com/jwks.json.
为此,请参阅此页面中有关 JWT 秘密字段 的部分:https://community.tyk.io/t/multiple-auth-schemes-for-single-api-definition/694/4
您需要每周刷新此文档,因为 Google 大约每两周滚动一次密钥。
可以使用以下 shell 命令制作此文档,仅使用 curl 和名为 jq: 的 JSON 命令行处理器
curl -s 'https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com' | jq '[ to_entries | .[] | {alg: "RS256", kty: "RSA", use: "sig", kid: .key, x5c: (.value | sub(".*"; "") | sub("\n"; ""; "g") | sub("-.*"; "")) } ] | {"keys": .}'
这是此命令行的输出:
% curl -s 'https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com' | jq '[ to_entries | .[] | {alg: "RS256", kty: "RSA", use: "sig", kid: .key, x5c: (.value | sub(".*"; "") | sub("\n"; ""; "g") | sub("-.*"; "")) } ] | {"keys": .}'
{
"keys": [
{
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"kid": "7d2f9f3fb83d6337497b6f7cd2cff4dfa5c2e8b8",
"x5c": "MIIDHDCCAgSgAwIBAgIIQq3HE7JcUqIwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UEAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTkwNDAyMjEyMDUwWhcNMTkwNDE5MDkzNTUwWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tlbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMx8FOZclZRLlXQNR53h+mYYjo9X4Hi38dAsLrP2iRzt8PowOnqx7hxpr9Ag7NKTSAOXTUAmObCRkEooRLe6jcScu+nttpjqqvtOyzhTl2szbdsiRhveXmOwMMbZ/DCkXll6i2NoeeRxVy4qxMDMPM6pokjsUyuq9wkWH+fiUG8rYSZVhpCqfOtqoTBu0zf+PyuGDPlLKKkE6Y7WKp5Go/tIMS6kTz5vhnA3M0HNWdZDy+06kT0eTxajzcs/QXiqmMzJEsJ7ln0Qh1KnOZwMH578y9GYM3ytMdiybDQM0c4cWtLp0REjlKyzqh0LLA7fmdjmEmIgOSy1wzftcKnfYNECAwEAAaM4MDYwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADggEBAFpLrULiau0nFLjRXxt9lwjgft1elBt265Hu88TU3132Wbh00Yvm7hlOA34gVIVNPcgT5lCxc4qVLXbA6yPtnyDubvULmVxyCSKfX/2M4Td+yPF99xR3VVCpATPAVjtOo819Q/Of+icQlmSoy/I0lFJewwrqcRc0eC9UgzF+EvGXHzIfoNlQgFjf/fnG1OV7d2Zr8bj+Jk/zZwVRstKCTrPgyqCYe/y7PU9q0aIQnMRvYKdLj/TfaBolQ12Tlb2j+nGMrPH5uVsUUu6nZluhaMvmlhp8glvslmjlXCIuce/N8FSw7zVf/ofRrDzTw98N1DZG2aLRyRYdmsXDBqMaac8="
},
{
"alg": "RS256",
"kty": "RSA",
"use": "sig",
"kid": "ff1df5a15b5cf582b61a21385c0cfaedfdb6a748",
"x5c": "MIIDHDCCAgSgAwIBAgIIcqcNMyhOv18wDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UEAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTkwMzI1MjEyMDUwWhcNMTkwNDExMDkzNTUwWjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tlbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKnDRgOsHY55P2i7wX6Uh8YO/rBWmGgVgeBqCowbHopF5HA1EdF0NXSmBn1Myg+DLFqxf0nvsi8B5pjd/rNtVPX6OUIkAKGPyva/d2aQqsHliCFh81QDs2vHIeIAThbQZP514t/z2M79SWR7A0vRYcWf+I+eTL6Vf1nqO3cFwTJVtwiTPom+NjZKx7ukowtqm1mVef+FqceC5zx8D5wzLLtUx/tMPvnXaysSjNN+86cPKc02kumCqlt7Yuf5G9VptjAVqsQyL/X5WuIVuzkFrfh/IPidw7Wzm3s5u928aLNSNbFpEpeXqJ8utD4AZnfm9mg6PYNtFWIB/L6xf21iZOECAwEAAaM4MDYwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADggEBAEdXAGI27mRT+Qkz9vbGlGbKJZKLG6b6c/SAQkOZJDOX4sJ16WgbfsixGBEWmvMMiEwhWV0hbhTiEC22xUd7cRP6veRlKba4rKoYA0x3GJhpDpAviuKPFkCanLFlFOXouexQIxBudWm32B8YFpLW9ds8m9yFmQZwE5GZs1hJ1jb2z2u7AuZNdQnaQ7mKy7Vmt3yHb9NjPlvmQ//ijFR3Lw4XB3nlYcL77mjjd3fhBodfUFkPJpsY2wOQpRLxDbvjHsXSfsgQ+/a+9IjKj0F2YOu9HnvjTXCopWObA9AGV6HR2L6RGaRLTwH+xV2El8UrzTYFPPN/URLui3XtaGdiREg="
}
]
}
这个输出的内容必须保存在https://my-application-server.com/jwks.json
对应的文件中