【发布时间】:2012-08-29 09:08:06
【问题描述】:
我正在为一些开发实现一组 RESTful 服务,其中一个是身份验证服务。
此身份验证服务对两种身份进行身份验证:
- 应用程序。 基于 AppKey 的身份验证,因此客户端必须注册密钥才能访问其余服务。
- 用户。 基于众所周知的凭据(用户+密码)的用户身份验证,因此人类和机器可以通过客户端应用程序使用这些 RESTful 服务。
这些 RESTful 服务是无状态的。
当客户端应用程序根据身份验证服务进行身份验证时,或者当人或机器使用凭据作为身份进行身份验证时,这两个操作都会生成 AppToken 和 UserToken 分别。
这些令牌是加盐哈希,因此对 RESTful 基础架构的后续请求将在不共享 AppKeys 和 凭据 的情况下进行身份验证。
从完全无状态方法的角度来看,这些令牌不应存储在服务层的任何位置,而是以某种客户端状态(例如,Web 客户端将使用 HTTP cookies)。 这就是我当前的实现目前的工作方式。
因为使用这些令牌重新验证每个请求并让服务层接收来自客户端的令牌,因此它可以比较来自客户端的令牌和检查它是否是一个有效的令牌在服务层重新生成它并与客户端拥有的进行比较太昂贵了,我已经实现了一个服务层 AppToken 和 UserToken,两者都有到期日期和所有者(为其创建令牌的应用程序或用户),以便检查来自客户端的令牌是否存在于令牌存储中。
客户端如何以交互方式取消身份验证? 只是删除客户端安全状态。如果是 Web 客户端,它会丢弃身份验证 cookie 并刷新页面,客户端检测到没有身份验证 cookie 并将用户重定向到登录页面。
从 RESTful 服务的角度来看,这是一种无状态的非身份验证:客户端不知道具有服务层伪身份验证状态的技巧。 这只是一个服务实现细节——一个性能优化——。
我不会列出无状态服务的优点,因为我绝对确定这种方法是可行的方法,但我发现了一个问题:无状态身份验证/未身份验证意味着客户端不会通知服务器他们关闭会话,因此安全存储以大量无用记录结束。
如果服务客户端的会话时间有限(例如,1 小时、3 小时、一天...),这不是一个大问题,但是 如果用户必须经过身份验证会发生什么情况永远(8 个月,一年)?。 您如何区分什么是过期令牌?
有一些方法可以解决这种情况:
每当服务层收到请求时,它都会更新令牌到期日期,因此自动进程可能会丢弃那些已过期的令牌,从而定义令牌的任意到期时间(例如 24 小时)。
妥协架构的无状态特性,让客户端通知服务层他们不想再进行身份验证,因此服务可以将关联的令牌丢弃到客户端会话(但是等等……如果客户端关闭了 Web 客户端会发生什么?用户永远不会主动通知服务必须丢弃令牌……所以……僵尸令牌还在那里,所以自动化进程应该丢弃它们,但是。 .. 什么是僵尸令牌?我不喜欢这种方法)。
完全无状态身份验证、无存储、按请求身份验证。
这是问题!您建议的方法是什么 - 即使不是 1.、2. 或 3. - 为什么?
感谢您的长时间阅读 - 我真诚地相信问题的结论将对任何人都非常有用 -!
【问题讨论】:
-
你在服务层对token做了哪些检查,怎么这么贵?
-
@Henrik 令牌由一些用户信息+秘密盐+发出日期组成
-
盐的秘密是谁的?每个服务是否共享盐的知识,还是仅共享身份验证服务?
-
@Henrik 它在业务层面实现。此机密由身份验证管理器处理。顺便说一句,也许我迷路了,但似乎这个细节与我的问题无关。
-
盐用于增加熵,因此您不能在整个摘要/散列范围内使用彩虹表,但一次只能在单个散列 + 盐上使用。我不确定这就是你所追求的。因此,如果您的服务不知道盐,他们不知道如何重新创建哈希,那么您需要每个服务每次都与身份验证管理器对话,因为这就是知识所在。
标签: .net rest authentication .net-4.5 c#-5.0