如何在不暴露的情况下正确发送 JWT



所以我不确定我的问题是否真的适合堆栈溢出,但我会试一试,看看我对 JWT 的了解是否真的正确,或者我完全不在循环中。

因此,我创建的是一个服务器 API,用于读取从客户端应用程序发送的 POST 请求,并返回能够访问我创建的其余 API 所需的不记名令牌。

到目前为止,我有一个服务器 api,如果用户名和密码与登录名匹配,则创建持有者令牌。

一个简单的 POST 请求看起来像

{'username': 'hello', 'password': 'world'}

所以我所做的是我创建了一个从 JWT 编码的 JWT。带有密码的IO站点,如下所示:

{'username': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJhcnJ5In0.-TCwkrPr8dq4WqsckaWNG7G2ddn7e97hH0jkQ-1j5Bo',
'password': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzd29yZCI6ImF1dG9zbmtyIn0.mWvxW4xga_OQMLKxf5zfSP4bSV0KzLPSRpqapU-RbAw'}

但是我的主要问题是我应该如何处理客户端应用程序之间的连接 ->第一个/token 请求才能获得持有者令牌?

似乎我确实需要以某种方式在客户端应用程序中"硬编码"用户名和密码才能访问我的 API,但我觉得这不是正确的方法,因为这样您就可以读取网络日志并将相同的请求发送到服务器,您将永远获得一个新的持有者令牌,您可以操纵我的服务器 api。

我的问题是,我应该怎么做才能无法在客户端应用程序中公开我的用户名和密码,并且能够通过我的服务器 API 进行操作?因为我的服务器所做的是它使用 secret 解码来自 JWT 的用户名和密码,如果用户名和密码与我的服务器 api 用户名和密码匹配,则匹配。但是感觉就像通过使用已经完成的编码JWT令牌暴露我的用户名和密码,您仍然可以使用这些值并做任何您想做的事情?

客户端应用示例:

import requests
headers = {
'accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
}
data = {'username': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJhcnJ5In0.-TCwkrPr8dq4WqsckaWNG7G2ddn7e97hH0jkQ-1j5Bo',
'password': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzd29yZCI6ImF1dG9zbmtyIn0.mWvxW4xga_OQMLKxf5zfSP4bSV0KzLPSRpqapU-RbAw'}

response = requests.post('http://127.0.0.1:8000/token', headers=headers, data=data, verify=False)

从您的描述来看,您的用例中的客户端似乎代表自己而不是代表人类用户行事。

在这种情况下,适用的 OAuth2 授权类型称为"客户端凭据",其中客户端将"授权"标头中的客户端凭据(通常是客户端 ID 和客户端密钥(发送到授权服务器。然后,授权服务器将共享访问令牌和/或刷新令牌,这些令牌需要以 cookie 的形式存储在客户端(通常以 JWT 的形式(,并与每个后续请求一起发送到资源服务器。"授权"标头的唯一特别之处在于它告诉整个HTTP基础设施不要在任何共享缓存中缓存该值。

现在,问题是,我们如何存储客户端机密。我们应该在客户端中对其进行硬编码吗?当然不是。通常,处理此问题的最安全方法是将其存储在密码保管库中。通常,保管库将机密、密码和证书存储在防篡改硬件安全模块 (HSM( 中。(但在没有保管库的情况下,通常将加密形式的机密存储在单独的文件中(。

剩下的唯一问题的答案是,客户端如何连接到保管库。保险库信任平台(比如AWS或Kubernetes或任何其他云平台(。在这些平台中启动 VM 或容器时,平台会在容器中注入令牌。然后,应用程序将使用令牌连接Vault,该保管库可以验证令牌与平台的真实性。

相关内容

  • 没有找到相关文章

最新更新