是的,这个问题的标题是可怕的,但在试图找出如何说出来的5分钟后,我继续前进!
我正在为一个正在接受重大改革的软件平台启动独立授权服务器(C#,Web API,Azure)的设计阶段。我阅读了Taiseer Joudeh(http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity)关于这个主题的总是伟大的文章,并且实现主要是在我的头脑中。授权服务器的外部用户(将从各个端点使用服务的应用程序开发人员)将拥有一个门户,他们可以登录并管理他们的帐户,白名单IP地址,选择他们的API版本(类似于Stripe的做法)它)和其他各种管理任务。
我挂起的是两个不同的真实世界(今天发生)场景,其中一个呼叫者在其访问权限上有多个单元访问API和处理事务。下面是对当前要求的总结(如果有一个我没有考虑过的好论据,可能会改变,没有任何内容),以及我正在努力解决的两个场景。
问题:我是否允许我的授权客户(可以访问auth服务器上的帐户的客户定义1-N个&#34;应用程序&#34;它们将拥有自己的刷新/身份验证令牌... < / p>
事实:
我的许多客户运行多个服务器,通过平台处理交易。这些可以专用于Azure中的前台服务器或辅助角色以及介于两者之间的所有内容。
实现必须支持API调用之间的长时间,而无需完全重新进行身份验证。有些客户每月拨打一次电话。
我喜欢Box的实现:刷新令牌有效期为60天,访问令牌有效期为1小时。每个新的访问令牌都提供一个新的刷新令牌。
门户网站内的客户必须&#34;白名单&#34;他们的IP地址和新的访问令牌(以及新的访问令牌)只会发送给来自其中一个白名单IP的请求。
令牌必须包含要求在目标应用中使用令牌的应用程序的版本号(控制器选择)。有关详细信息,请参阅SO。 每一次&#34;刷新&#34;访问令牌发出新的刷新令牌。
刷新令牌未被烧毁&#34;直到第一次使用新访问令牌成功调用(如果新访问令牌在传输过程中丢失,客户端可以使用先前的刷新令牌获取新的访问令牌)。
我还没有做到这一点,但考虑到列入白名单的IP地址,它看起来似乎是一个增值点。
访问令牌的寿命很短(15分钟)。这既用于安全目的,也用于API版本迁移,因为版本将在令牌中。
关注: 多呼叫者场景中的两种不同场景:
在内置服务器上对我来说,在这种情况下完全有意义的是允许授权服务器门户中的客户定义1-n个呼叫者,每个呼叫者代表其中一个服务器这将提出要求。在这种情况下,没有共享缓存,允许共享刷新/访问令牌非常困难(如果不是不可能)。多台服务器第一次收到401时会发生什么?
WorkerRole(Azure):与On Prem Server配置相比,如果没有一些配置文件向导,每个可扩展单元都知道,就很难支持多个刷新/访问令牌它的位置(即它恰好是什么实例编号)。在这种情况下,客户可以访问共享缓存,并且可以实现并发收集等以跟踪当前刷新和访问令牌,并且在获得新访问令牌时,命中401的第一个调用者可以阻止其他调用者。
*根据布莱斯的答案进行更新*
关于客户端/应用程序凭据实际上两者都有,但我想澄清我现在的计划是什么,现在包括Thanktecture。我把它用在WS-Fed(v2我相信)的日子里,并没有为OAuth2看过它,但我会。
每个被授予API访问权限的客户(将其视为父帐户,然后在其下面拥有许多没有API访问权限的子帐户)将登录API门户(可能是基于Identity 2.0的w) / MVC或Angular前端)。在此门户中,他们将能够管理他们的帐户(为特定应用程序设置API版本等)。这是他们能够创造&#34;创造&#34;应用程序凭据,假设未实现动态注册。他们不会将Identity 2.0门户帐户信用用于其clientID。我很可能会使用一些强大的随机密码生成代码动态生成这些凭据(clientId和secret)。
我提到的初始问题的核心是我是否应该允许创建一个且只有一个客户端ID /机密,而不是每个clientID约束强制执行一个活动的刷新/身份验证令牌,或允许他们创建1- N并在该特定客户端ID /秘密之间创建1:1。
我不太可能需要特定客户针对特定应用程序的多个不同权限/角色。换句话说,如果CustomerA能够针对特定的URI调用POST,那么这将永远是真的,如果它发生变化,它将全面改变该客户。因此,我的计划是在客户级别(我上面提到的身份2.0门户网站帐户)设置应用程序特定权限,如果我使用帐户下的1-N clientID /机密,则会创建各种抽象。这些clientID / secret中的每一个都将继承这些权限。
我很惭愧承认,因为我开始爬下众所周知的兔子洞,我忽略了考虑允许在clientID / secret和主动刷新/身份验证令牌之间建立1:多关系的可能性。我有点想到它们会被束缚在一起而且只会成为一对。在这种情况下,如果用户有3个针对API运行的活动代理,则第三个获取身份验证令牌(因此是新的刷新令牌)会破坏其他两个代理获取新身份验证令牌的能力没有完全重新验证,因为代理3的刷新令牌是最后一个被授予的。
在1:许多场景中,来自白名单IP的每个身份验证代理使用clientID / secret将获得有效的刷新/身份验证令牌供自己使用。这真的解决了我所描述的所有问题,但却降低了一点点的能见度&#34;谁&#34;如果呼叫者在负载均衡器后面,那么呼叫者是真正有多少呼叫者。
当然,我试图实现的平衡是稳固的安全性,以及最终用户的相对轻松的实现,最终用户现在熟悉用于身份验证和授权的json对象实现中的键值对。 p>
答案 0 :(得分:0)
开发了类似的架构后,我可以看到你支持两种场景中的一种(或者两种场景):
允许客户在应用程序的多个实例(服务器或工作者角色)之间共享应用程序/客户端凭据。
要求客户为已安装的应用程序的每个实例使用一组唯一的应用程序/客户端凭据。
您没有提及使用客户端或应用程序级凭据,但我假设这些凭据正在使用中,而不是支持未注册的客户端。换句话说,当客户注册其应用程序(或应用程序实例)并提供其IP地址时,您将返回唯一的客户端ID(通常是客户端密钥)。然后,客户的应用程序使用此客户机ID和机密来请求访问令牌和刷新令牌组合。
对于每个应用程序实例,访问令牌和刷新令牌组合应该是唯一的。单个应用程序实例请求多个活动访问/刷新令牌也是可接受的(并且有些常见)。例如,当您有两个可能需要不同授权级别的API端点时,应用程序可以请求两个访问/刷新令牌,每个令牌具有与这些端点一起使用的不同范围值(授权)集。在您的方案中,每个应用程序实例(服务器或工作者角色)都会请求它自己的访问/刷新令牌组合并独立回收这些组合。我认为更有趣的问题是这些应用程序实例是共享相同的客户端凭据,还是使用唯一的集合。
OAuth 2.0威胁模型鼓励使用特定于安装的客户端机密(请参阅https://tools.ietf.org/html/rfc6819#section-5.2.3.4)。它使用的措辞“授权服务器可能向特定客户端的不同安装发出单独的客户端标识符和相应的秘密”(强调我的)。但是,我在实践中发现,几乎没有什么可以阻止客户端重复使用本机和移动应用程序的多个实例的客户端凭据。
通过对白名单客户IP地址的额外保护,我认为如果不为每个应用程序实例使用唯一的客户端凭据,那就没问题了。话虽如此,您应该充分考虑系统特有的所有威胁,这些威胁可能会试图将此作为一个弱点。解决此问题的一种可能方法是使用动态客户端注册过程自动为每个新应用程序实例发出客户端凭据。有关此示例,请参阅OpenID Connect动态客户端注册1.0(http://openid.net/specs/openid-connect-registration-1_0.html)或草案OAuth 2.0动态客户端注册协议(https://tools.ietf.org/html/draft-ietf-oauth-dyn-reg-21)。同样,这可能难以强制客户使用动态客户端注册,而不是简单地重用一组应用程序/客户端凭据。
最后,我建议您不要从头开始设计OAuth2授权服务器,而是将优秀的开源Thinktecture IdentityServer(https://github.com/thinktecture/Thinktecture.IdentityServer.v3)(无联盟)平台视为可扩展的起点。