【问题标题】:How to handle authentication and authorization with thrift?如何使用 Thrift 处理身份验证和授权?
【发布时间】:2011-06-05 00:52:34
【问题描述】:

我正在开发一个使用节俭的系统。我希望检查客户身份并进行 ACL 操作。 Thrift 是否为这些提供任何支持?

【问题讨论】:

    标签: authentication authorization rpc thrift


    【解决方案1】:

    不直接。做到这一点的唯一方法是使用一种在服务器上创建(临时)密钥的身份验证方法,然后更改所有方法,以便第一个参数是此密钥,并且它们都会另外引发未经身份验证的错误。例如:

    exception NotAuthorisedException {
        1: string errorMessage,
    }
    
    exception AuthTimeoutException {
        1: string errorMessage,
    }
    
    service MyAuthService {
        string authenticate( 1:string user, 2:string pass )
            throws ( 1:NotAuthorisedException e ),
    
        string mymethod( 1:string authstring, 2:string otherargs, ... )
            throws ( 1:AuthTimeoutException e, ... ),
    }
    

    我们使用这种方法并将我们的密钥保存到一个安全的 memcached 实例中,密钥超时 30 分钟,以保持一切“快速”。收到AuthTimeoutException 的客户需要重新授权并重试,我们有一些防火墙规则来阻止暴力攻击。

    【讨论】:

    • @JensG 不,您希望以加密格式发送密码并在服务器端检查该编码字符串。 Bcrypt 对此很有用,因为通过网络发送的字符串可能与存储的字符串不完全匹配,但使用 bcrypt 算法检查时可能仍然有效。
    • 如果是这种情况,您将不会发送明文密码,但如果攻击者能够读取散列密码,他可以重放身份验证调用并访问您的服务。
    • 可以使用 SSL 保护通信。 doublecloud.org/2014/01/… 描述了如何创建服务器密钥对并使用客户端中的证书来加密流量。这种机制应该提供一个安全通道,您可以按照答案中的描述实现自定义身份验证/授权。
    【解决方案2】:

    自动化和权限等任务不被视为 Thrift 的一部分,主要是因为这些事情(通常)与应用程序逻辑相关,而不是一般的 RPC/序列化概念。 Thrift 目前唯一支持开箱即用的是TSASLTransport。我自己不能说太多,只是因为我从来没有觉得有必要使用它。

    另一种选择可能是使用THeaderTransport,不幸的是,在撰写本文时它仅使用 C++ 实现。因此,如果您打算将它与其他语言一起使用,您可能需要投入一些额外的工作。不用说我们接受捐款...

    【讨论】:

      【解决方案3】:

      有点晚了(我想很晚了),但几年前我已经为此修改了 Thrift 源代码。

      为此刚刚向https://issues.apache.org/jira/browse/THRIFT-4221提交了一张带有补丁的票。

      看看那个。基本上,该提议是添加一个“BeforeAction”钩子来实现这一点。

      示例 Golang 生成的差异

      +       // Called before any other action is called
      +       BeforeAction(serviceName string, actionName string, args map[string]interface{}) (err error)
      +       // Called if an action returned an error
      +       ProcessError(err error) error
       }
      
       type MyServiceClient struct {
      @@ -391,7 +395,12 @@ func (p *myServiceProcessorMyMethod) Process(seqId int32, iprot, oprot thrift.TP
              result := MyServiceMyMethodResult{}
              var retval string
              var err2 error
      -       if retval, err2 = p.handler.MyMethod(args.AuthString, args.OtherArgs_); err2 != nil {
      +       err2 = p.handler.BeforeAction("MyService", "MyMethod", map[string]interface{}{"AuthString": args.AuthString, "OtherArgs_": args.OtherArgs_})
      +       if err2 == nil {
      +               retval, err2 = p.handler.MyMethod(args.AuthString, args.OtherArgs_)
      +       }
      +       if err2 != nil {
      +               err2 = p.handler.ProcessError(err2)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-19
        • 2019-06-09
        • 1970-01-01
        • 1970-01-01
        • 2012-07-05
        • 2017-08-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多