我不是安全专家,所以我正在寻找人们在我设计的认证方案中挖洞,或者指出一个更好的现有方案来实现相同的目标:
问题概述
我有一个接口,客户端维护会话生命周期(它是Web服务器上的HTTP会话,但这并不重要)。
无状态服务器提供一些需要对呼叫者进行身份验证的服务(服务器能够执行此身份验证)。
然而,服务器不希望在每次调用时都必须验证调用者,例如,通过在每次调用中传递凭证。 (身份验证过程可能很昂贵。)
还希望不在服务器上维护会话状态。首先,它只是要求一个脆弱的解决方案,在客户端和服务器上都有独立的会话超时(客户端上的那个不能被删除),并且为了获得可靠的会话生命周期,似乎需要服务器超时在服务器上(而不是依赖客户端在适当的时间显式结束会话)。另一方面,服务器未设置为存储此类状态。
服务器有一个明确的authenticate
方法。问题是:服务器如何验证,当调用另一个方法时,调用者以前使用authenticate
方法进行了身份验证,而不在服务器上存储任何会话状态?
提议的解决方案
这是我提出的方案:
authenticate
方法接受凭据作为输入参数。验证成功后,服务器返回两件事:
在进一步的方法调用中,客户端将这两个值传递回服务器。然后,服务器解密加密的{username,timestamp}元组。如果解密的时间戳与客户端也发送的未加密值匹配,则服务器知道客户端先前已经过身份验证(因为这是获取有效加密值的唯一方法)。解密的用户名告诉服务器哪个用户已经过身份验证。
加密密钥的有效期可以通过仅允许当前时间 x 小时内的时间戳来强制执行。这与会话超时不同,但它限制了恶意方可以使用受损时间戳的窗口。
因此
我担心这个计划在很多方面都是天真的。你看到了什么弱点或坏的逻辑?
答案 0 :(得分:0)
如果有人关心(考虑到这个问题引起了多少关注,这似乎不太可能!),我们最终实施了一个如上所述的方案。
但有些细节有所不同: