从哪里获取 Public 密钥以在 Java 或 Kotlin 中验证 JWT 令牌
Where to get Public key for validating a JWT Token in Java or Kotlin
我在后端将 Kotlin 与 Vertx 结合使用,前端在从 One Login 获得身份验证后向我转发了一个 JWT 令牌。现在,我想确保令牌有效而不是假的(编造的)。如果我遵循 link,它说我需要一个 public 密钥才能创建一个 JWTAuth 对象,我可以使用它来调用身份验证进行验证。
https://vertx.io/docs/vertx-auth-jwt/kotlin/
我想知道在哪里可以获得 public 密钥?
我不知道 OneLogin,但从他们的文档中我可以看出他们是 SAML/OpenId Connect 提供商,因此可以轻松地从他们的配置中检索 public 密钥。根据他们的文档,您可以从以下位置找到您的实例配置:
https://<subdomain>.onelogin.com/oidc/.well-known/openid-configuration
从这个文件中,您应该查找键 jwks_uri
,它将包含一个值,如:https://acme.onelogin.com/oidc/certs
。如果你得到这个 URL 你会得到一个 JSON 类似于:
{
"keys": [
{
"kty": "RSA",
"kid": "JRcO4nxs5jgc8YdN7I2hLO4V_ql1bdoiMXmcYgHm4Hs",
"n": "z8fZsz...GHSTAoQw",
"e": "AQAB"
}
]
}
此文件是一个 JSON Web 密钥(链)此 JSON 可以提供给 JWTAuth 以加载密钥并进行所需的验证。作为 3.6 的旁注,模块 OAuth2 中将提供适当的 OpenId Connect Discovery
支持,这意味着您不再需要 fiddle,如果您的提供者和所有内容,只需传递 URL将被正确配置。
非常感谢您的中肯回答。我能够访问 JSON Web 密钥,我也将它输入 JWTAuth.create,现在 JWTCreate 没有抛出任何异常。然而,provider.authenticate 总是无法验证它,即使我使用的是从前端发送的经过验证的 JWT 令牌。
我使用以下方式创建 JWTAuth 对象。
var jsonObject = JsonObject("<I Copied all contents of Json Web Key here.>")
var provider = JWTAuth.create(myvertx, jsonObject)
然后我用了
var idJson = JsonObject()
idJson.put("jwt", myJWTToken)
var optionsJson = JsonObject()
optionsJson.put("ignoreExpiration",true)
idJson.put("options", optionsJson)
provider.authenticate(idJson, { asyncresult ->
println("Is authenticated = ${asyncresult.succeeded()}")
})
但是当我尝试使用 Vertx 方式通过 PubSecKeyOptions 和 JWTAuthOptions 提供 public 密钥时,通过从 OneLogin 证书 URL 复制密钥,它抛出了一个异常 "InvalidKeyException"
Caused by: java.security.InvalidKeyException: IOException: DerInputStream.getLength(): lengthTag=71, too big.
at sun.security.x509.X509Key.decode(X509Key.java:398)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:86)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
... 51 more
我在后端将 Kotlin 与 Vertx 结合使用,前端在从 One Login 获得身份验证后向我转发了一个 JWT 令牌。现在,我想确保令牌有效而不是假的(编造的)。如果我遵循 link,它说我需要一个 public 密钥才能创建一个 JWTAuth 对象,我可以使用它来调用身份验证进行验证。 https://vertx.io/docs/vertx-auth-jwt/kotlin/
我想知道在哪里可以获得 public 密钥?
我不知道 OneLogin,但从他们的文档中我可以看出他们是 SAML/OpenId Connect 提供商,因此可以轻松地从他们的配置中检索 public 密钥。根据他们的文档,您可以从以下位置找到您的实例配置:
https://<subdomain>.onelogin.com/oidc/.well-known/openid-configuration
从这个文件中,您应该查找键 jwks_uri
,它将包含一个值,如:https://acme.onelogin.com/oidc/certs
。如果你得到这个 URL 你会得到一个 JSON 类似于:
{
"keys": [
{
"kty": "RSA",
"kid": "JRcO4nxs5jgc8YdN7I2hLO4V_ql1bdoiMXmcYgHm4Hs",
"n": "z8fZsz...GHSTAoQw",
"e": "AQAB"
}
]
}
此文件是一个 JSON Web 密钥(链)此 JSON 可以提供给 JWTAuth 以加载密钥并进行所需的验证。作为 3.6 的旁注,模块 OAuth2 中将提供适当的 OpenId Connect Discovery
支持,这意味着您不再需要 fiddle,如果您的提供者和所有内容,只需传递 URL将被正确配置。
非常感谢您的中肯回答。我能够访问 JSON Web 密钥,我也将它输入 JWTAuth.create,现在 JWTCreate 没有抛出任何异常。然而,provider.authenticate 总是无法验证它,即使我使用的是从前端发送的经过验证的 JWT 令牌。
我使用以下方式创建 JWTAuth 对象。
var jsonObject = JsonObject("<I Copied all contents of Json Web Key here.>")
var provider = JWTAuth.create(myvertx, jsonObject)
然后我用了
var idJson = JsonObject()
idJson.put("jwt", myJWTToken)
var optionsJson = JsonObject()
optionsJson.put("ignoreExpiration",true)
idJson.put("options", optionsJson)
provider.authenticate(idJson, { asyncresult ->
println("Is authenticated = ${asyncresult.succeeded()}")
})
但是当我尝试使用 Vertx 方式通过 PubSecKeyOptions 和 JWTAuthOptions 提供 public 密钥时,通过从 OneLogin 证书 URL 复制密钥,它抛出了一个异常 "InvalidKeyException"
Caused by: java.security.InvalidKeyException: IOException: DerInputStream.getLength(): lengthTag=71, too big.
at sun.security.x509.X509Key.decode(X509Key.java:398)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:86)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
... 51 more