【问题标题】:Hyperledger Fabric: implementing chaincode level access controlHyperledger Fabric:实现链码级访问控制
【发布时间】:2019-09-22 19:21:24
【问题描述】:

我想对某些方法实现链码级别的访问控制。因此,例如,我希望调用的链代码方法只有在执行请求的用户具有与世界状态中请求的资产字段匹配的特定身份时才能执行。

https://hyperledger-fabric.readthedocs.io/en/release-1.4/chaincode4ade.html,官方文档说:

“Chaincode 可以通过调用 GetCreator() 函数将客户端(提交者)证书用于访问控制决策。此外,Go shim 提供了扩展 API,可从提交者的证书中提取客户端身份,用于访问控制决策,无论是它基于客户身份本身、组织身份或客户身份属性。

例如,表示为键/值的资产可能包括客户端的身份作为值的一部分(例如作为指示资产所有者的 JSON 属性),并且只有该客户端可能被授权更新未来的键/值。客户端身份库扩展 API 可在链码中用于检索此提交者信息以做出此类访问控制决策。”

这完美地反映了我的情况:我的资产包含一个字段所有者,我希望删除方法只能由作为该资产所有者的用户对资产执行,即如果他的身份 - 用户名 - 匹配所有者字段。

我的问题是官方文档中提供的解决方案描述了使用“客户端身份(cid)库”(https://github.com/hyperledger/fabric/tree/master/core/chaincode/shim/ext/cid)从证书中提取用户信息的可能性。但在我的情况下,我有 Java 和 Javascript 的链码,并且(我认为)我只能使用 GetCreator() 方法,它将用户证书作为字节数组作为输出。

如何从证书中提取我需要的信息?可能吗?是否可以使用我的 Java 和 Javascript 链码中的 CID 库?

【问题讨论】:

    标签: hyperledger-fabric hyperledger hyperledger-chaincode chaincode


    【解决方案1】:

    我也在寻找此功能,但现在似乎已添加。 FAB-15895 将 ClientIdentity.java 添加到 Java 链代码(参见 commit),它允许查询证书以获取信息。希望它成为 Fabric 的下一个版本 - v1.4.4 的一部分。

    【讨论】:

      【解决方案2】:

      CID 库只是一个语法糖包装器,它有助于在链码中使用身份进行操作,本质上在 GoLang 中所做的事情或提取信息的方式是:

      
          serializedID, _ := stub.GetCreator()
      
          sId := &msp.SerializedIdentity{}
          err := proto.Unmarshal(serializedID, sId)
          if err != nil {
              return shim.Error(fmt.Sprintf("Could not deserialize a SerializedIdentity, err %s", err))
          }
      
          bl, _ := pem.Decode(sId.IdBytes)
          if bl == nil {
              return shim.Error(fmt.Sprintf("Could not decode the PEM structure"))
          }
          cert, err := x509.ParseCertificate(bl.Bytes)
          if err != nil {
              return shim.Error(fmt.Sprintf("ParseCertificate failed %s", err))
          }
      
          fmt.Println(cert)
      

      这可以通过以下方式在 Java 中完成:

              try {
                  Identities.SerializedIdentity identity = Identities.SerializedIdentity.parseFrom(stub.getCreator()); 
                  StringReader reader = new StringReader(identity.getIdBytes().toStringUtf8()); 
                  PemReader pr = new PemReader(reader); 
                  byte[] x509Data = pemReader.readPemObject().getContent();
                  CertificateFactory factory = CertificateFactory.getInstance("X509"); 
                  X509Certificate certificate = factory.generateCertificate(new ByteArrayInputStream(x509Data));
      
              } catch (InvalidProtocolBufferException e) {
                  e.printStackTrace();
              }
      

      【讨论】:

      • 很高兴它帮助了你。
      • 嗨!非常感谢您的回答,它非常有帮助。我用那个代码解决了(非常相似):```Identities.SerializedIdentity identity = Identities.SerializedIdentity.parseFrom(stub.getCreator()); StringReader reader = new StringReader(identity.getIdBytes().toStringUtf8()); PemReader pr = new PemReader(reader); byte[] x509Data = pemReader.readPemObject().getContent(); CertificateFactory 工厂 = CertificateFactory.getInstance("X509"); X509Certificate 证书 = factory.generateCertificate(new ByteArrayInputStream(x509Data)); ```谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 2021-05-19
      相关资源
      最近更新 更多