【问题标题】:Client authentication on Public Client公共客户端上的客户端身份验证
【发布时间】:2013-01-12 13:08:42
【问题描述】:

研究OAuth2.0我终于找到了这2个参考: RFC6749 section 2.3, RFC6749 section 10.1

如果我错了,请纠正我:

可以使用未注册的客户端,但您必须自己管理它们,存在安全风险。

  • 我应该如何管理它们?

一些更具体的问题:

  1. 根据定义,Native Application (a Public Client indeed)能够安全地存储其凭据(client_id + secret)。是unregistered client 吗?如果我无法使用密钥验证/验证它,我还应该怎么做?
  2. 客户端注册≠端点注册:首先是关于注册Client Credentials(client_id + secret);第二个关于注册Client Redirection Endpoints。重定向端点注册是否足以授予客户端的真实性?
  3. Client Credential Grant 是否使用 same 凭据 (client_id + secret) 进行客户端注册?

我想你可以通过解释this paragraph (RFC6749 section 10.1) 的含义来回答我。

请给我一些参考和实例,说明如何实现授权服务器和资源服务器的交互。

谢谢

【问题讨论】:

    标签: oauth-2.0


    【解决方案1】:

    tl;博士:

    1. 无法使用client_idclient_secret 对本机客户端进行身份验证。如果您需要对客户端进行身份验证,则必须实施不将共享机密委托给客户端的身份验证方案(或让最终用户参与客户端身份验证讨论)。根据您的应用程序的安全模型,您可能不需要对客户端进行身份验证。
    2. 重定向端点通常不足以对客户端进行身份验证(尽管exceptions exist)。
    3. “客户端凭据”授权类型可以使用授权服务器支持的任何客户端身份验证机制,包括客户端注册时提供的凭据。

    我读到的要点是,您可以信任机密客户的client_id(阅读:“用户名”)和client_secret(阅读:“密码”)来使用您的服务对他们进行身份验证。第三方应用程序不可能[1] 使用该客户端的凭据来代表自己,因为有理由认为它们被安全地存储在远离窥探的地方。

    然而,公共客户端无法做出这样的保证——无论是基于浏览器的应用程序还是本地桌面应用程序,客户端的 id 和密码都会分发给整个世界。可以合理地假设此类应用程序最终将落入熟练的开发人员和黑客手中,他们可以深入挖掘客户端并提取 id 和秘密。因此,第 10.1 节明确指出:

    The authorization server MUST NOT issue client passwords or other
    client credentials to native application or user-agent-based
    application clients for the purpose of client authentication.
    

    好的。因此公共客户端无法通过密码进行身份验证。不过……

    The authorization server MAY issue a client password or other
    credentials for a specific installation of a native application
    client on a specific device.
    

    此异常有效,因为它将客户端的身份验证绑定到特定设备,这意味着即使有人带着客户端的秘密离开,他们也无法重复使用它。然而,在这个例外中隐含的是,“特定设备上的特定安装”必须是唯一可识别的、难以欺骗的,并且是该客户端身份验证过程的组成部分。

    并非每个本机应用程序都能满足这些标准,基于浏览器的应用程序当然不能,因为在它运行的环境中没有唯一可识别或难以欺骗的东西。这导致了几个选项 - 您可以将客户端视为未经身份验证,或者您可以提出更合适的身份验证机制。

    身份验证舞蹈的关键是共享秘密——只有授权服务器和身份验证客户端才知道。 对于公共客户,客户本身没有什么是秘密的。值得庆幸的是,有很多选择,而且我不只是在谈论 RFID 密钥卡和生物识别技术(尽管这些都是完全可以接受的)。

    作为一个思想实验,让我们考虑一个基于浏览器的客户端。我们可以合理地假设一些事情:它在浏览器中运行,它从特定域提供服务,并且该域由客户端的作者控制。身份验证服务器应该已经有一个客户端重定向 URI,所以我们已经有了一些东西,但是正如规范所指出的那样:

    A valid redirection URI is not sufficient to verify the client's
    identity when asking for resource owner authorization but can be
    used to prevent delivering credentials to a counterfeit client
    after obtaining resource owner authorization.
    

    所以重定向 URI 是我们应该检查的东西,但不是我们可以信任的东西,很大程度上是因为域可能被欺骗。但是服务器本身不能,所以我们可以尝试向域询问只有客户端域的服务器才知道的东西。最简单的方法是认证服务器需要第二个(“私有”)URI,与客户端在同一个域中,客户端的密钥将在其中托管。当客户端应用程序发出授权请求时,服务器然后“签入”第二个 URI相对于客户端报告的主机名,并查找共享密钥(仅应向授权公开服务器的 IP 地址)来验证客户端。

    当然,这不是一个完美的解决方案。它不适用于每个应用程序,很容易出错,并且可能需要大量工作才能实现。存在许多潜在的身份验证机制(包括高度特定的和高度通用的),并且任何不将私有数据委托给客户端应用程序的机制都适用于这个问题空间。

    我们的另一个选择是不实施进一步的身份验证,并将客户端视为未经身份验证。这与未注册的客户明显相同,但区别很微妙。未注册客户是身份未知的客户。未经身份验证的客户端是其身份已知但不受信任的客户端。两种类型的客户端的安全含义是相同的:都不应该委托私人数据。然而,授权服务器是否选择同等对待这两种情况似乎是由实施者决定的。例如,API 拒绝来自未注册客户端的所有连接,并向任何注册的客户端提供公共只读内容(即使没有验证客户端的身份)可能是有意义的。 p>

    然而,实用主义可能会胜出——未经身份验证的客户端与 SSL“错误”基本上没有什么不同,当您的浏览器无法验证网站 SSL 证书的真实性时,您偶尔会看到这些错误。浏览器将立即拒绝继续并准确报告原因,但允许用户通过保证服务器的身份自行承担风险。类似的工作流程可能对许多 OAuth2 应用程序有意义。

    为什么验证客户的身份很重要?如果不这样做,信任链就会中断。您的应用程序的用户信任您的应用程序。授权工作流程确定您的用户也信任 客户端,因此您的应用程序应该信任客户端。在不验证客户端身份的情况下,另一个客户端可以出现并承担受信任客户端的角色,并拥有其所有安全权限。有关客户端身份验证的所有内容都有助于防止违反信任。

    希望这有帮助!

    [1]:服务器入侵,即您的应用程序的源代码落入恶意之手,是一个例外,并且针对这种情况内置了其他保护措施。话虽如此,规范还特别指出,简单的用户名/密码组合不是最安全的选择:

    The authorization server is encouraged to consider stronger
    authentication means than a client password.
    

    【讨论】:

    • 是的,这很有帮助!文档很清楚,但需要非常仔细阅读并具有全局性的想法。很难把所有的点放在一起。在您使用“私有”URI 的示例中,您不是仅使用 ID 来识别客户端吗?如果有人窃取/获取了 client_id,那么他就可以访问服务器进行的身份验证。这就像“啊,是你,我知道你的秘密/私人数据,继续”
    • 不完全。在我给出的示例中,我提到的“私有 URI”可能看起来像 https://example.com/sooper/secret。由http://example.com/client 提供服务的应用程序与https://authexample.com 的授权服务器对话以请求授权令牌。为了对客户端应用程序进行身份验证,授权服务器将考虑给它的client_id请求来自的域(在本例中为example2.com)。然后授权服务器将与https://example.com/sooper/secret 对话,并根据原始密码检查密码。
    • 那么@pvande,真的有任何解决方案来验证桌面应用程序客户端吗?我什至在您的回答中也看不到任何内容:\
    • @pvande 我仍然很困惑。如果 client_id/client_secret 被泄露(比如在浏览器应用程序中被硬编码),黑客仍然需要知道用户的凭据才能获得 access_token。如果黑客拥有用户凭据,他为什么还要担心 client_id/client_secret?
    • @IM_AG 假设我的服务realbits.comoauth-host.com 的机密客户端。 Alice是oauth-host.com的用户,刚刚注册realibits.com并成功授权。此时,oauth-host.com 已经注意到 Alice 的身份验证 cookie 和 realbits.comclient_id,并且realbits.com 有一个 access_token 代表 oauth-host.com 处的那对。如果攻击者 (fakebits.com) 拥有我的客户端 ID 和密码,并说服 Alice 进行身份验证,他们将透明地收到具有 realbits.com 的所有权限的 access_token...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    相关资源
    最近更新 更多