【问题标题】:Java code for verification of FusionAuth HS256 signed id token用于验证 FusionAuth HS256 签名 id 令牌的 Java 代码
【发布时间】:2022-02-12 01:57:55
【问题描述】:

如何使用 FusionAuth java Client 库验证 HS256 ID Token?

描述:我在 FusionAuth 中创建了一个应用程序,它生成了一个客户端 ID 和客户端密码,我没有触及任何其他部分/选项卡,如 JWT 等,默认 JWT 签名算法是 OIDC 标准 HMAC SHA256。

我尝试使用以下代码方法基于公钥验证令牌,但它不适用于 HS256 签名令牌,我在互联网上搜索发现公钥不适用于 HS256

能否请您提供一个 Java 代码,以使用 FusionAuth Java 客户端库 (https://github.com/FusionAuth/fusionauth-jwt) 验证 HS256 签名令牌。 也请告诉我是否需要在 FusionAuth 管理控制台上进行任何其他配置。

我尝试过的代码:它给出了空白的公钥。

List<JSONWebKey> keys = JSONWebKeySetHelper.retrieveKeysFromJWKS("http://localhost:9011/.well-known/jwks.json");

Map<String, Verifier> publicKeyVerifiers = new HashMap<String, Verifier>();

JWT jwtDecoded = JWT.getDecoder().decode(idToken, publicKeyVerifiers);

【问题讨论】:

    标签: authentication oauth-2.0 jwt fusionauth hmacsha256


    【解决方案1】:

    应用收到的令牌通常应使用非对称密钥进行签名。然后,您可以使用通过 JWKS 端点提供的签名公钥来验证令牌的数字签名。令牌最主流的算法是RS256。也许您需要按照建议 here? 重新配置。我认为你的代码也可以工作。

    HS256 是一种对称算法,感觉不对,因为客户端只有拥有完整的签名密钥才能验证 JWT。这使得恶意客户端能够铸造他们自己的令牌,而只有授权服务器才能做到这一点。因此,如果 JWT 曾经使用对称密钥进行签名,JWKS 端点将不会提供令牌签名密钥。

    意思是说 Curity 有一个很好的相关文档:

    【讨论】:

    • 您好 Gary Archer - 我之前遇到过这个话题,但我忽略了它,感谢您指出这一点,我将与我的团队开始对此进行一些研究,以了解我们是否应该转向 RS256 .我还向@mooreds 询问了这个问题,以了解他是否可以帮助我们做出决定。非常感谢您的回复。
    • 加里的优点!
    • 酷 - 我添加了上面的链接,以防对您的团队有用以供将来参考。
    【解决方案2】:

    README 中似乎有一个示例:

    // Build an HMC verifier using the same secret that was used to sign the JWT
    Verifier verifier = HMACVerifier.newVerifier("too many secrets");
    
    // Verify and decode the encoded string JWT to a rich object
    JWT jwt = JWT.getDecoder().decode(encodedJWT, verifier);
    
    // Assert the subject of the JWT is as expected
    assertEquals(jwt.subject, "f1e33ab3-027f-47c5-bb07-8dd8ab37a2d3");
    

    https://github.com/FusionAuth/fusionauth-jwt#verify-and-decode-a-jwt-using-hmac

    使用 HMAC 签名,您需要将密钥(上例中的 "too many secrets")分发到所有需要验证 JWT 的位置。

    【讨论】:

    • 非常感谢您的回复,看来我在自述文件中忽略了这一部分。您能否确认我需要将我的 client_secret 替换为“too many secrets”?
    • 使用默认的秘密值。您可以在 key master 部分的 admin ui 中找到它。如果它对您有用,请不要忘记接受答案。
    • 你好@mooreds - 谢谢它的工作,我接受了答案。请跟进问题 1. if (jwtDecoded.audience.equals("") && jwtDecoded.issuer.equals("www.acme.com") && (jwtDecoded.expiration.toEpochSecond() > (System .currentTimeMillis()/1000) )) { // 有效的 id token } A] 没有“www”的发行者的值 jwtDecoded.issuer = acme.com B] 到期时间是 ZonedDateTime 对象,如果 FusionAuth 和验证码正在运行2 个不同的分区服务器,那么仅使用系统时间会不会有问题,因为它将是本地系统时间?
    • 这取决于您的安全配置文件以及您对令牌的操作。一般来说,我建议像@gary 那样使用非对称密钥,因为它确实降低了签名密钥被盗的风险。但是,如果您对令牌消费者也有严格的控制,并且签名速度非常重要,那么使用 HS256 可能会更好。我在这里写了更多关于此的内容:fusionauth.io/learn/expert-advice/tokens/building-a-secure-jwt
    • 您好@mooreds 感谢您的回复,我可以做到。 stackoverflow 的新手,仍在学习 :-)
    猜你喜欢
    • 2023-03-12
    • 2021-05-04
    • 2016-07-06
    • 2014-12-14
    • 2021-11-16
    • 2017-11-19
    • 2019-11-01
    • 2020-02-18
    • 2017-05-19
    相关资源
    最近更新 更多