在 NodeJS 后端使用 JWT 和 Active Directory 身份验证

Using JWT with Active Directory authentication in NodeJS backend

我正在构建一个由 Angular 前端和 Node.JS 后端组成的 Intranet Web 应用程序。应用需要使用企业Active Directory进行身份验证和授权。

我正在考虑如何以安全的方式最好地实施它。我计划使用 Active Directory node module 与 AD 进行实际通信,以在用户登录时进行身份验证,并检查某些受限操作的安全组成员资格等。

但是,我不太确定授权后端端点的最佳方式是什么。 AD 模块不提供任何 token/ticket,即使我认为 Kerberos 用于实际的身份验证过程。在我开发的其他经过身份验证的应用程序中,我在用户登录时生成了一个 jsonwebtoken,然后在每个后端路由中传递并验证了该令牌,这在针对 AD 进行身份验证时也是个好主意吗?

编辑:问题的第二部分产生了单独的线程:Best practices for server-side handling of JWT tokens

此外,我还有一个更普遍的担忧,即实际验证令牌的最佳做法是什么。假设用于生成 JWT 的 "secret" 遭到破坏(在我的场景中,许多人可能可以访问系统的源代码,但不能访问系统本身)。我是否正确地认为恶意用户可以仅使用此信息代表任何给定用户生成令牌,而无需使用 AD 进行身份验证在我的 API 请求中使用该令牌?令牌通常使用 jwt.sign(payload, secretOrPrivateKey, options) 生成。 或者,假设恶意用户可以获取实际令牌(在它过期之前)。对我来说,似乎不必知道用户的用户名和密码,安全性现在降低到必须知道用户名和 JWT 秘密。这是一个合理的担忧吗?我应该怎么做才能防止这种情况发生?

到目前为止,我最大的希望是使用服务器端会话在登录后存储有关当前用户的信息,这样即使在访问后端端点时恶意生成并使用了令牌,除非用户有实际上通过了登录路由,使用 AD 进行了身份验证,并因此在会话中存储了一些信息。

我还考虑过在 each API 端点中使用 AD 进行实际身份验证,但这需要在每个请求中发送 AD username/password,这反过来又要求敏感信息必须存储在客户端的会话存储或本地存储中,这很可能是个坏主意。

所以,问题:

1) 将 AD 授权与 JWT 结合作为不记名令牌是否合理,或者使用 AD 进行身份验证构建安全后端+前端的首选方式是什么?

2) 如果 JWT 是个好主意,那么使用 JWT 保护端点的最佳实践是什么?使用服务器端会话是否合理?

有趣的是,我发现了很多关于如何最好地实现基于令牌的身份验证的示例(一般来说,或者特别是使用 NodeJS),但其中许多似乎在某种程度上存在缺陷。

1) Is it reasonable to combine AD authorization with JWT as bearer token or what is the preferred way to build a secure backend + frontend utilizing AD for authentication?

这是合理的,但如果您已经在使用 Kerberos 和 AD 对用户进行初始身份验证,您可以考虑使用 s4u2proxy constrained delegation,它允许服务向 KDC 出示用户的服务票证并获取(受授权检查)后端服务的票证(并重复需要的服务)。

如果您有 很多 后端服务需要联系,一个 JWT 承载 所有 所需的所有授权声明执行授权策略的服务可能是更好的选择。

2) If JWT is a good idea, what is the best practice for securing endpoints using JWT? Is using a server side session reasonable?

通用关键安全实践适用:

  • 从不 将密钥明文存储在任何地方的非易失性存储器中。
  • 最好不要将加密密钥存储在服务器上的附加存储中,如果服务器受到威胁,它们将受到离线攻击。使它们仅在服务器启动时对主机可用。
  • 确保密钥 material 驻留在安全内存中,以便它不能交换到磁盘(and/or 使用加密交换)。
  • 使用 public 密钥算法,这样就不需要在多个主机上存在密钥。
  • 考虑使用 hardware security module (HSM)。