在项目中一般需要设置不同用户的不同权限,fabric中的链码执行同样如此,可以通过用户标签来实现。
流程:sdk申请用户时,指定用户标签,链码执行时获取对应标签实现链码调用权限验证。
sdk代码(注册用户):
/**
* 注册用户并进行登记
* @param orgName 所在组织
* @param userName 用户名
* @param pwd 用户密码
* @return 一个新的用户
*/
public FabricUser registerAndEnrolledUser(String orgName, String userName, String pwd) throws Exception {
FabricUser user = getUser(orgName, userName);
RegistrationRequest request = new RegistrationRequest(userName, orgName.toLowerCase() + AFFILIATION);
request.setSecret(pwd);
//开始设置值
request.addAttribute(new Attribute("org","org1"));
request.addAttribute(new Attribute("peer","peer0.org1.example.com"));
request.addAttribute(new Attribute("user", "fang"));
request.addAttribute(new Attribute("dept", "test"));
EnrollmentRequest req = new EnrollmentRequest();
req.addAttrReq(); // empty ensure no attributes.
user.setEnrollmentSecret(ca.register(request, admin));
if (!user.getEnrollmentSecret().equals(pwd)) {
throw new RuntimeException("设置密码异常,您设置的密码与系统返回的密码不一致:yourPwd:" + pwd + ", system:" + user.getEnrollmentSecret());
}
user.setEnrollment(ca.enroll(userName, pwd, req));
//测试
user.setMspId(orgName + "MSP");
client.setUserContext(user);
return user;
}
链码操作代码:
func (t *TestChaincode) getUser(stub shim.ChaincodeStubInterface, args []string) pb.Response {
logger := getLogger(stub)
logger.Info(fmt.Sprintf("get args: %s", args))
//getting submitter of the transaction
logger.Info("begin to read userInfo")
sinfo, err := cid.New(stub)
if err != nil {
logger.Error(fmt.Sprintf("get submitter of the transaction: %s", sinfo))
return shim.Error(err.Error())
}
id, _ := sinfo.GetID()
logger.Info(fmt.Sprintf("get clientIdentityId: %s", id))
mspId, _ := sinfo.GetMSPID()
logger.Info(fmt.Sprintf("get clientIdentityMSPId: %s", mspId))
//读取dept的相关值
dv, df, err := sinfo.GetAttributeValue("dept")
if err != nil {
logger.Error(fmt.Sprintf("get deptAttrVal err: %s", err.Error()))
} else {
if df {
logger.Info(fmt.Sprintf("get deptAttrVal: %s", dv))
} else {
logger.Debug(fmt.Sprintf("not found deptAttrbute"))
}
}
//读取org
ov, of, err := sinfo.GetAttributeValue("org")
if err != nil {
logger.Error(fmt.Sprintf("get orgAttrVal err: %s", err.Error()))
} else {
if of {
logger.Info(fmt.Sprintf("got orgAttrVal: %s", ov))
} else {
logger.Debug(fmt.Sprintf("not found orgAttrbute"))
}
}
//读取peer
pv, pf, err := sinfo.GetAttributeValue("peer")
if err != nil {
logger.Error(fmt.Sprintf("get peerAttrVal err: %s", err.Error()))
} else {
if pf {
logger.Info(fmt.Sprintf("got peerAttrVal: %s", pv))
} else {
logger.Debug(fmt.Sprintf("not found peerAttrbute"))
}
}
//读取user
uv, uf, err := sinfo.GetAttributeValue("user")
if err != nil {
logger.Error(fmt.Sprintf("get userAttrVal err: %s", err.Error()))
} else {
if uf {
logger.Info(fmt.Sprintf("got userAttrVal: %s", uv))
} else {
logger.Debug(fmt.Sprintf("not found userAttrbute"))
}
}
return shim.Success([]byte("请看日志"))
}
日志部分截图:
通过自定义标签即可实现权限的基本控制,具体设计就看公司项目了。