我正试图为我的RESTful API实现基于JWT的无状态认证。
据我所知,JWT基本上是一个加密字符串,在REST调用期间作为HTTP头部传递。
但如果有人窃听请求并窃取令牌怎么办?那么他将能够冒充我的身份进行请求吗?
实际上,这个问题适用于所有基于令牌的身份验证。
如何防止这种情况?使用像HTTPS这样的安全通道?
我正试图为我的RESTful API实现基于JWT的无状态认证。
据我所知,JWT基本上是一个加密字符串,在REST调用期间作为HTTP头部传递。
但如果有人窃听请求并窃取令牌怎么办?那么他将能够冒充我的身份进行请求吗?
实际上,这个问题适用于所有基于令牌的身份验证。
如何防止这种情况?使用像HTTPS这样的安全通道?
我是一个处理身份验证的Node库express-stormpath的作者,所以我会在这里提供一些信息。
首先,JWT通常不会被加密。虽然有一种方法可以加密JWT(参见:JWEs),但出于许多原因,这在实践中并不常见。
接下来,任何形式的身份验证(使用JWT还是不使用)都容易受到中间人攻击。当攻击者可以查看您通过互联网进行请求时的网络流量时,就会发生此类攻击。这就是你的ISP、NSA等所能看到的。
这就是SSL帮助防止的:通过从计算机加密您的网络流量->在认证时与某个服务器,第三方监视您的网络流量的人无法看到您的令牌、密码或任何其他东西,除非他们以某种方式能够获得服务器的私钥(不太可能)。这就是所有形式的身份验证都要求使用SSL的原因。
假设有人能够利用您的SSL并能够查看您的令牌:您的答案是,是的,攻击者将能够使用该令牌来冒充您并向您的服务器发出请求。
现在,这就是协议发挥作用的地方。
JWT只是身份验证令牌的一个标准。它们可以用于几乎任何事情。 JWT之所以有点酷,是因为您可以嵌入额外的信息,并且可以验证没有人对其进行了更改(签名)。
然而,JWT本身与“安全”无关。基本上,JWT与API密钥差不多:只是您用来验证某个服务器的随机字符串。
让您的问题更有趣的是正在使用的协议(很可能是OAuth2)。
OAuth2的工作方式是,它旨在为客户端提供临时令牌(例如JWT)进行身份验证,仅在短时间内使用!
这样设计的想法是,如果您的令牌被盗取,攻击者只能在短时间内使用它。
使用OAuth2,您必须定期重新通过提供用户名/密码或API凭据来进行身份验证,然后交换令牌。
由于此过程会不时发生,因此您的令牌将经常更改,使攻击者难以在不经过大量麻烦的情况下不断冒充您。
希望这有所帮助^^
我知道这个问题很老了,但我想分享我的看法,也许有人可以改进或提供一个理由来完全拒绝我的方法。我在一个基于RESTful API的HTTPS中使用JWT。
为了使它工作,你应该始终发行短期的令牌(取决于大多数情况,在我的应用程序中,我实际上将exp
声明设置为30分钟,并将ttl
设置为3天,因此只要令牌的ttl
仍然有效并且令牌未被列入黑名单,就可以刷新此令牌)。
对于认证服务
,为了使令牌无效,我喜欢使用内存缓存层(在我的情况下是Redis)作为JWT黑名单
/禁止列表
,具体取决于一些标准:
(我知道这会破坏RESTful哲学,但存储的文档真的很短暂,因为我为其剩余的生存时间-ttl
声明-列入黑名单)
注意:列入黑名单的令牌不能自动刷新
user.password
或user.email
(需要密码确认),认证服务会返回一个新的令牌并使先前的令牌无效(列入黑名单)。因此,如果你的客户端检测到用户的身份已经被某种方式破坏,你可以要求该用户更改其密码。如果你不想使用黑名单,你可以(但我不鼓励你)将iat
(发行时间)声明与user.updated_at
字段验证(如果jwt.iat < user.updated_at
,那么JWT就无效)。最后,你可以像其他人一样正常验证令牌。
注意2: 不建议将令牌本身作为缓存的键(令牌非常长)。我建议生成并使用UUID令牌来代替,并将其用于jti
声明。这很好,我认为你可以使用相同的UUID作为CSRF令牌,通过返回一个带有secure
/non-http-only
的cookie以及使用js正确实现X-XSRF-TOKEN
头。这样,您就避免了创建另一个令牌进行CSRF检查的计算工作。
抱歉稍微晚了点,但我有类似的担忧,现在想对此做出一些贡献。
1) rdegges提出了一个很好的观点,即JWT与“安全”无关,仅验证是否有人搞乱了有效载荷或未签名;ssl可以帮助防止违规行为。
2) 现在,如果ssl也被某种方式破坏,那么任何窃听者都可以窃取我们的bearer token(JWT),并冒充真实用户,接下来可以采取的下一步是从客户端请求"proof of possession"(拥有证明)的JWT。
3) 现在,采用这种方法,JWT的呈现者拥有特定的Proof-Of-Possession(POP)密钥,接收方可以通过加密确认请求是否来自同一真实用户。
我参考了Proof of Possesion这篇文章,并对这种方法深信不疑。
如果能够做出任何贡献,我将非常高兴。
干杯 (y)
我们能否将请求生成此JWT令牌的初始主机的IP地址作为声明的一部分添加到令牌中?现在,当JWT被窃取并从不同的机器上使用时,当服务器验证此令牌时,我们可以验证请求的机器IP地址是否与作为声明的一部分设置的IP地址匹配。这将不匹配,因此令牌可以被拒绝。另外,如果用户尝试通过将自己的IP地址设置为令牌来操纵令牌,则令牌将被拒绝,因为令牌已被更改。