php 和 java json-rpc 实现兼容并支持 ssl

Posted

技术标签:

【中文标题】php 和 java json-rpc 实现兼容并支持 ssl【英文标题】:php and java json-rpc implementations compatible and with ssl support 【发布时间】:2014-04-10 15:41:57 【问题描述】:

我在一家公司工作,他们要求我编写一个 android 应用程序来处理存储在集中式数据库 (mysql) 上的敏感数据,因此我需要编写一个 Web 服务来将 Android 应用程序与数据库通信,并且由于在该连接中会传输敏感数据,因此我需要为此使用安全连接。

所以,我决定使用 json-rpc 进行通信,这就是为什么我正在寻找两个 json-rpc 实现:php 中的服务器端(实际上他们拥有的主机正在运行 PHP 4.3)和客户端在它们之间兼容并支持 SSL 的 Java 端(与 Android 兼容)。

【问题讨论】:

【参考方案1】:

我相信有人可能会提出一些建议,但这可能不是获得图书馆选择帮助的最佳场所。

另一方面,如果您就某些库/实现提出具体问题,您可能会得到明智的答案。这种方法的一个常见问题是提问者不知道要问什么问题! (这会导致重新发明***,通常会在安全方面做出糟糕的决策。

JSON-RPC (1.0/1.1/2.0) 协议组非常简单。有数百个 PHP 实现。我不太了解评估 Android 库,但 this 之前的 SO 问题给出了建议的 Android 客户端实现。

我将主要处理您问题的服务器端部分,为您提供具体的答案可以询问您可能正在评估的特定实现。

服务器端 PHP JSON-RPC 实现的注意事项:

    您将如何处理传输身份验证? 您将如何处理 RPC 方法授权? 您将如何处理运输安全问题? 您是否需要处理位置/命名/两种样式的方法参数 您是否需要处理/发送通知消息? 您需要处理批处理请求吗?您需要发送批量回复吗? PHP 实现在各种异常/警告条件下的表现如何? PHP 实现如何建议或减轻 PHP 数组集/列表对偶性? 您是否需要实施 SMD? 您的 Web 服务是否还需要执行其他 HTTP 级别的路由? (例如:静态资源)

您将如何处理传输身份验证?

假设您使用 HTTP 作为传输层协议,您将如何验证 HTTP 请求?你会使用密码/HTTP-auth/证书/SRP/其他身份验证吗?你会继续信任一个开放的套接字吗?身份验证后您会使用 cookie 来扩展信任吗?

这些并不是真正与 JSON-RPC 相关的问题,但许多服务器端实现对您将如何进行身份验证做出了各种假设。有些人只是把这完全取决于你。您在此处的选择可能会极大地影响您对图书馆的选择。

您将如何处理 RPC 方法授权?

您可能会决定,一旦用户通过身份验证,他们就可以调用所有公开的方法。如果没有,那么您需要一种机制来允许单个用户(或他们的组)执行某些方法,但不能执行其他方法。

虽然这些问题存在于 JSON-RPC 信封中,但 JSON-RPC 协议规范并未直接解决这些问题。

如果您确实需要实现方法-“授权”方案,您可能会发现某些服务器实现使这变得困难或不可能。寻找一个在将 JSON-RPC 请求路由到单个 PHP 函数之前公开挂钩或回调的库,以便您可以检查请求并将它们与身份验证相关信息结合起来,以决定如何/是否处理这些请求。如果库让您在此处使用自己的设备,您可能不得不在 JSON-RPC 公开的 PHP 函数中复制大量用户/方法检查代码。

您将如何处理运输安全问题?

假设您使用 HTTP 作为传输层协议,那么显而易见的答案就是 TLS。所有常见的 SSL/TLS 安全问题都适用于此,许多 SE/SO 问题已经解决了这些问题。

既然你控制着客户端的实现,你至少应该考虑:

选择强密码并禁止使用弱密码 以理智的方式处理(或不处理!)重新谈判 避免已知有问题的实现/功能(例如:OpenSSL 1.0.1-1.0.1f、heartbeat [CVE-2014-160])。

您是否需要处理位置/命名/两种样式的方法参数

一些 JSON-RPC 服务器端实现更喜欢 JSON-RPC 信封的 params 参数看起来像 params: [412, "something"](位置),而其他人更喜欢 JSON-RPC 信封的 params 参数看起来像params: "type": "something", "num_events": 412 (已命名)。还有一些人可以毫无问题地处理任何一种风格。您应该根据这个“兼容性”问题来选择客户端和服务器库。

您需要处理/发送通知消息吗?

Notification 消息由客户端或服务器发送给对方,以便随着时间的推移传达一些更新/完成的状态。发送方(表面上)不应该期望对“通知”消息的响应。

大多数 JSON-RPC 实现使用 HTTP(S) 作为其传输协议;由于 HTTP 没有实现双向异步通信,因此您无法正确实现“通知”消息。

由于您的客户端是 Android,您可以使用 TCP 套接字上的纯 JSON 文本作为传输协议(而不是 HTTP);由于 TCP 确实允许双向异步通信(一旦建立套接字),那么您可以正确地实现“通知”消息。

一些库通过 HTTP 传输实现客户端到服务器的通知,方法是对通知消息进行排队,然后在请求式消息上捎带通知(可能使用“批处理”请求——请参阅下一个问题)。类似地,一些库通过在响应式消息上捎带通知(可能使用“批处理”响应)来通过 HTTP 传输实现服务器到客户端的通知。

还有其他库通过使用 WebSockets 作为其传输协议来使用 HTTP。由于这确实允许双向(本质上)异步通信,因此这些库可以正确地实现“通知”消息。

如果您不需要它,您将在选择传输协议(以及因此实现)时有更多选择。

您需要处理批处理请求吗?你需要发送批次吗 回复?

有时希望在单个请求/响应中发送/处理请求/响应/通知组(所谓的“batch”消息)。 JSON-RPC 信封的id 参数用于区分批处理中的请求/响应。

如果您不需要这个,那么您在选择实现时会有更多选择(“批处理消息”是 JSON-RPC 实现中最常被忽略的特性)。

PHP 实现在各种异常/警告条件下的表现如何?

PHP 有多种向程序员传播错误条件的方法,也有不同类型的错误条件。服务器端实现是否以一致的方式处理“抛出”异常和 PHP 级错误? error_reporting 配置是否合适(库是否在本地更改它)?库与调试库(例如:xdebug)的交互是否会很差?

服务器端实现是否正确地将 JSON-RPC 级别的错误与 HTTP 级别的错误隔离开来? (即:它是否可以防止请求生命周期内的错误/异常变成像 500: Internal Server Error 这样的 HTTP 级错误。

服务器端实现是否与您的身份验证和授权措施正确交互? (即:可能需要将相关错误分别提升为 401: Unauthorized403: Forbidden HTTP 状态)。

在通过 HTTP 或 JSON-RPC 传递错误时,服务器端实现是否会“泄露”有关您的实现或数据源的敏感信息?

对于 JSON-RPC 网络服务,这些是非常重要的问题,将用于安全意识的设置。通过阅读其文档很难评估给定实现的这一点。您可能需要:

深入研究其源代码以查看所采用的错误处理策略,并 执行广泛的测试以避免泄漏和错误情况的意外传播。

PHP 实现如何建议或减轻 PHP 数组集/列表对偶性?

PHP 是一种蹩脚的 语言。那里。我说过:-)

JSON-RPC 实现者处理的一个常见问题是如何正确地将 JSON arrays 和 JSON objects 映射到语言原生数据结构。虽然 PHP 对索引数组和关联数组使用相同的数据结构,但大多数语言都没有。这包括 javascript,其语言特性/限制为 JSON(以及 JSON-RPC)规范提供了依据。

在 PHP 中,no 方法可以将 empty 索引数组与 empty 关联数组区分开来,并且可能会出现各种顽皮的东西对现有数组进行了处理(例如:在现有索引数组上设置关联键)已经提出了各种解决方案来处理这个问题。

一种常见的缓解措施是 JSON-RPC 实现可能会强制作者在返回它们之前将所有预期关联数组转换为 (object),然后在运行时拒绝任何(隐式或预期)索引数组- 确认键或非顺序索引。其他一些服务器端库强制作者注释他们的方法,以便在“编译”时知道预期的数组语义;有些人试图通过自动内省来确定打字(坏坏坏)。还有其他服务器端库让这个机会发生。

服务器端 PHP JSON-RPC 实现中存在/缺失的缓解措施可能非常能说明其质量 :-)

您需要实施 SMD 吗?

SMD 是 JSON-RPC “-like” 协议的非标准化扩展,允许发布 WSDL-like 有关 web 服务端点和功能的信息(没有类,尽管命名空间的约定可以是发现那里)它暴露了。

有时,“打字”和“授权”问题与用于实现 SMD 的类/函数“注释”分层。

客户端或服务器实现都不太支持此“标准”:-)

您的网络服务是否还需要执行其他 HTTP 级别的路由? (例如:静态资源)

一些服务器端实现对在 HTTP 请求周期中多久会被要求参与做出各种假设。如果 JSON-RPC 实现实现 HTTP 服务器本身,或者约束所有接收到的 HTTP 消息的内容,这有时会使事情复杂化。

您通常可以通过将已知 JSON-RPC 请求代理到单独的 Web 服务器,或将非 JSON-RPC 请求路由到单独的 Web 服务器来解决这些问题。

如果您需要从同一个 Web 服务器提供 JSON-RPC 和非 JSON-RPC 资源,请问问自己,服务器端 JSON-RPC 实现是否使这成为不可能,或者它是否让您跳过箍来解决它.

【讨论】:

感谢您提供如此建设性的回答,我会考虑到这一点,但是我已经找到了一些很好的库来解决这个问题。

以上是关于php 和 java json-rpc 实现兼容并支持 ssl的主要内容,如果未能解决你的问题,请参考以下文章

为 java 和 javascript 推荐一个 JSON-RPC 库 [关闭]

JSON-RPC轻量级远程调用协议介绍及使用

如何通过远程方法发送 json-rpc http post 请求并在 java 中传递加密参数

使用标准 JSON-RPC 实现的优势

Go & PHP json-rpc 通信

Swagger 和 json-rpc