在 JAVA ee 中使用 JWT 保护 REST 服务

Posted

技术标签:

【中文标题】在 JAVA ee 中使用 JWT 保护 REST 服务【英文标题】:Securing REST services with JWT in JAVA ee 【发布时间】:2017-11-17 21:09:11 【问题描述】:

我不熟悉网络令牌安全性,并且我正在尝试实现一个需要它但到目前为止没有运气的场景。我查看了许多教程、代码示例和项目,但它们要么太高级,要么只是代码块,要么明确声明此代码用于学习目的,而不是用于生产。

我的要求如下:

我有 3 个服务需要由多个外部经销商 Web 应用程序调用。 我需要确保从经销商应用程序到我们的应用程序的呼叫。我们将使用 SSL 进行通信。

我正在使用 JBOSS EAP7 和 Java ee,并且我计划使用 JWT 的实现(如 jjwt)。

我在网上找到的典型场景是客户端应用程序首先调用身份验证服务(我们编写的)传递应用程序 ID 和秘密(字符串)密码以获取 JWT 令牌。在此之后,应用程序在每次调用 3 个服务时都传递这个令牌,我们必须在接受每个请求之前验证它。

我的问题如下:

    当应用程序调用获取令牌时,它是否需要传递使用我们提供的公钥加密的请求,还是因为我们使用 SSL 而不需要? 如果我们需要使用私钥/公钥,是否有一个简单的好示例来展示如何使用 Java 生成它们以及如何使用它们来加密/解密请求?

    令牌生成。我不确定我们是否需要在发送之前加密令牌本身。一些网站谈论使用 base64 加密,还有一些谈论使用私钥加密签名。我对 JWS 和 JWE 概念感到困惑。是否有一个很好的示例或教程可以指导我如何安全地生成令牌?

    在这种情况下,JWT 令牌的典型到期时间是多少,他们是否需要在每次服务调用之前调用并获取新令牌?如果令牌过期,客户端应用程序是否必须在再次调用之前检查它是否过期,或者等待我们的服务返回错误?

    是否有一个简单的示例说明如何通过请求传递令牌以及如何在服务器上对其进行验证?

    如果可以重复使用,客户端应用是否需要将令牌存储在 cookie 或会话中?

谢谢

【问题讨论】:

【参考方案1】:
    最好使用 PKI,因为您可以使用应用的公钥来验证请求确实来自受信任的应用。 Base64 编码用于传递凭据 (clientid:secret) 以换取(未加密的)JWT 这取决于您的用例场景,安全性和可用性之间总是需要权衡取舍。它通常从几分钟到几小时(甚至更多)不等,但它肯定必须至少持续几个调用(以避免由于大量请求而导致的瓶颈)。理想情况下,客户也会检查是否过期(原因与前面介绍的相同)。 Google 是您的朋友,甚至还有专门的libraries。 客户端肯定需要将令牌保存在某个地方以便能够重复使用它。

【讨论】:

以上是关于在 JAVA ee 中使用 JWT 保护 REST 服务的主要内容,如果未能解决你的问题,请参考以下文章

使用JWT或OAuthv2保护REST + AngularJS

保护未经身份验证的 REST API

JWT 数字签名如何保护?

使用 Spring 安全性和 JWT 在 REST 中使用 <img> 标签访问私有图像

使用 JWT (Node.js + mongoose) 在 REST API 中管理用户权限的最佳方法

如何保护 Django Rest Framework 中注册和登录的 API?