【问题标题】:DotNetOpenID - Identity Provider behind a firewall?DotNetOpenID - 防火墙后面的身份提供者?
【发布时间】:2010-08-02 16:18:03
【问题描述】:

查看 OpenID 协议,似乎依赖方需要向身份提供者发送请求。在我们的情况下,这并不完全理想,因为身份提供者位于防火墙后面——我们的服务器将无法发出请求。但是,访问我们网站的用户(客户端,例如 javascript 或重定向)将能够。所以我的问题是:OpenID 是否支持防火墙后面的身份提供者?如果没有,是否有一种安全的方法来实现这一点?

编辑:

客户端在其防火墙后面有一个 Web 服务器。他们有员工访问我们的网站,因此能够访问我们的网站和位于其防火墙后面的网络服务器——但是,我们的服务器无法访问。身份提供者驻留在他们的网络服务器上,位于防火墙后面——我们的应用程序(依赖方)需要能够使用此内部员工身份提供者进行员工身份验证。

【问题讨论】:

    标签: asp.net openid dotnetopenauth


    【解决方案1】:

    OpenID 依赖方必须能够验证用户获得的断言是否真正来自 OpenID 提供者。否则,您的 RP 很容易受到简单攻击。

    传统的签名验证需要 RP 服务器直接联系 OP 服务器。由于在您的情况下这是不可能的,您唯一的选择是硬编码 RP 和 OP 之间的共享关联秘密。您为该关联创建一个关联句柄和一个加密的强机密,并将其告知 RP 和 OP,并且它永不过期。然后,您的 RP 发送的每个身份验证请求都必须要求 OP 使用该特定关联句柄。
    当然,永不过期的关联本身也存在安全风险。您可以(部分)通过确保它是 HMAC-SHA256 关联而不仅仅是 HMAC-SHA1 来缓解这种情况。

    最后,用户标识符发现通常需要从 RP 到 OP 的直接 HTTP 连接,但这可以通过使用标识符委托(在指向防火墙后面的 OP 的非防火墙服务器上设置标识符)轻松避免。或者,您的硬编码发现结果解决方案(包括 OP 端点)也适用于专门的解决方案。您必须小心阻止由此带来的所有安全风险(例如确保标识符确实来自您硬编码的 URL 集,否则人们可以从其他 OP 端点欺骗身份。

    由于您使用的是 DotNetOpenAuth,因此您可以创建自己的 IDirectWebRequestHandler 类并将其设置在您的 OpenIdRelyingParty.Channel.WebRequestHandler 属性上。此处理程序将有机会拦截到 [server-behind-firewall] 的传出 HTTP 请求,并通过简单地合成您自己的 HTTP 响应来“重定向”请求,该响应是防火墙后面的服务器将产生的 XRDS,如果您只能达到目标。每个 OP 应该只有两个 XRDS 文档(一个是 OP 标识符,另一个是 OP 断言的所有 claim_id)。这应该让您的发现在身份验证之前和之后都正常工作。

    【讨论】:

    • 我正在研究这个项目,同时学习 OpenID,所以这是很好的信息。不过有一个问题——我们的解决方案是专门的,是否有可能通过首先访问 OP 来建立 RP 和 OP 之间的关联(OP 建立关联?)。我们将有一个 RP 和许多 OP(与规范相反)。这样,OP 可以与我们的 RP 建立服务器端关联(OP 向 RP 发出请求)。
    • 恐怕这行不通。仅仅访问 OP 并不会在 RP 和 OP 之间建立关联。如果所有 OP 都在防火墙后面,则您需要对每个 RP-OP 对之间的关​​联进行硬编码(唯一!)。再次提醒您,请非常小心谨慎地验证签名和标识符,否则您将打开自己进行身份欺骗。我真的很害怕你是 OpenID 的新手做这么先进的事情。 OpenID 没有针对这种情况进行优化,您可能希望在这种情况下考虑其他协议。
    • 我是新手,因为这只是我的第三次实现——之前从未做过这种类型的集成(听起来像是滥用 OpenID?)。你会推荐什么协议?本质上,我们正在做的是拥有一个 SaaS 网站,并且我们的供应商希望使用他们的自定义凭据(在他们的防火墙后面,例如 LDAP)登录。我们不想引入打开防火墙的麻烦,但听起来这将是一个不错的可行选择。
    • 我不确定我是否可以进行标识符委托...我认为标识符选择不可能?这就是我们选择专用硬编码 EndPoint 的原因。我们将您的 DotNetOpenAuth 与该 JavaScript 解决方案结合使用。然后,我们有两种关联解决方案,一种是打开一个端口用于服务器到服务器的验证,另一种是固定的唯一 RP 和 OP 密钥,这些密钥每天都会由我们已经安装的 Windows 服务更改。至于确保标识符确实来自我们硬编码的一组 URL……如果我们使用 DotNetOpenAuth 会被标记吗?
    • 啊,我以为你是从头开始构建的。如果您使用的是 DotNetOpenAuth,那么我就不那么害怕了,因为 DNOA 不会让您走得太远,除非您竭尽全力去做。自动轮换共享关联机密的 Windows 服务非常棒!您可以通过自定义 IAssociationStore 将其与 DotNetOpenAuth 绑定,听起来您已经想通了。
    【解决方案2】:

    我不清楚你的问题。

    如果客户端能够访问防火墙后面的提供程序,那么服务器也应该——它使用与客户端相同的方法连接到相同的端口。

    如果无法从外部访问提供程序,那么它就毫无用处,就像任何其他无法访问的服务器一样。

    如果是您的依赖方无法与服务器建立传出连接,则无能为力——必须至少有一个从 RP 到 OP 的直接请求。

    总而言之:是的,依赖方必须能够连接到提供者。

    【讨论】:

    • 客户端在防火墙后面有一个服务器。他们有员工访问我们的网站,因此能够访问我们的网站以及位于他们防火墙后面的服务器——但是,我们的服务器无法访问。
    • 哦,我明白了。但是,服务器必须连接到提供者,否则客户端可能只是伪造服务器的响应。
    • 好吧,我就是这么想的……嗯……所以这完全不可行?使用客户端系统(员工的浏览器,例如 javascript、表单发布等)发送请求怎么样?我们可以完全控制他们防火墙后面的代码和我们这边的代码。
    • 看起来有一个客户端javascript部分RP示例? code.google.com/p/openid-selector ... 对此进行调查。
    • 你还是要和OP核实一下,否则你不能确定客户端提供的信息真的来自提供者。据我所知,即使有人设法在 javascript 中做到这一点,它作为一种身份验证机制也毫无价值。
    【解决方案3】:

    比在 RP 和 OP 之间硬编码共享关联密钥更简洁的替代方法,尝试使用 azure 或本地 ADFS 以及指向您的 OpenID 的 STS

    【讨论】:

      【解决方案4】:

      发现有一种方法可以使用以下示例代码创建客户端 RP:code.google.com/p/openid-selector。我修改了代码以适应我们的情况,它似乎工作。这里需要注意的是,您不使用自动发现,而是需要对端点进行硬编码(这在我的情况下是完全可以接受的)。

      【讨论】:

      • 糟糕糟糕。 code.google.com/p/openid-selector是依赖方的 Javascript 部分。这不是一个完整的解决方案。我怀疑您的服务器广泛容易受到攻击,因为它不验证签名,因此任何人都可以通过摆弄返回到您网站的 URL 以任何人身份登录。
      • 好的,谢谢提醒,RP 的这一部分就是我所需要的。我将在服务器端验证签名。
      猜你喜欢
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多