使用gRPC-web通过身份验证安全地公开gRPC服务

时间:2019-02-26 10:56:15

标签: authentication go grpc grpc-web

我们正在使用Improbable的gRPC-Web library向在浏览器中运行的Javascript客户端公开gRPC服务(在Go中实现)。该服务将与托管基于REST的API的现有前端Go服务并排放置。现有服务使用基于会话的身份验证来验证其用户(会话cookie + X double-submit cookies的XSRF保护,还使用每个会话的服务器端状态进行了验证)。

前端Go服务承载各种API端点,这些API端点可以在本地处理,也可以通过将请求代理到其他服务来实现。所有端点都通过Gin中间件处理程序链公开,该链实现了上述会话身份验证和XSRF保护检查。已经建议我们在现有的中间件后面托管gRPC-Web的gogrpcproxy component,以向世界展示我们的gRPC服务。

我有兴趣确保对传入的gRPC-Web请求进行身份验证的方法是安全的。已提出以下方法:

  • 基于令牌的身份验证 –即在gRPC请求元数据中传递承载令牌,这些令牌由后端gRPC服务验证。这与身份验证模型匹配,如果不涉及gRPC-Web,将通过该模型对本地gRPC调用进行身份验证。

    在此模型中,gRPC-Web的职责是实现浏览器和服务器之间的传输抽象,并封送往/自本地gRPC表示形式的请求;身份验证委托给支持gRPC服务。 gRPC-Web代理作为现有REST API外部的单独端点托管。

  • 基于会话的身份验证 –重新使用现有的会话身份验证中间件。在此模型中,grpcweb代理服务器托管在Gin处理程序链的后面。 Gin在接受请求之前会执行通常的检查,以验证相关cookie和XSRF标头的存在。

    此方法重用了许多现有的身份验证逻辑。但是,它需要传递XSRF标头,以确保Gin中间件接受该请求。在当前实现中,这可以通过设置请求元数据来实现,该请求元数据(当前)通过在出站HTTP请求上设置标头来实现。但是,我不清楚是否:

    • 是适当的,因为通过利用当前将元数据作为HTTP头传递的实现细节,看来是违反层的。这没有记录,并且可能会发生变化;
    • 与gRPC-Web的websocket传输兼容,该Websocket传输似乎没有将元数据传播到标头中,因为在传输任何请求之前已先拨号了websocket传输;
    • 将来会遇到潜在的安全问题,因为与前端服务的长期存在的gRPC-Web传输连接仅在首次建立时才由前端代理进行身份验证,而不是在每次请求时都进行连续验证(除非gRPC服务还可以验证请求元数据。

我的理解是,gRPC-Web试图模拟浏览器和服务器之间的gRPC传输,因此没有实现特定的身份验证逻辑。用于传递身份验证详细信息的标准gRPC机制不考虑基于隐式会话的状态,因此我更喜欢基于令牌的方法。

这是对可用选项的合理分析吗?

0 个答案:

没有答案