@@ -18,6 +18,7 @@ import com.jd.blockchain.ledger.core.OperationHandleContext; | |||
import com.jd.blockchain.ledger.core.SecurityContext; | |||
import com.jd.blockchain.ledger.core.SecurityPolicy; | |||
import com.jd.blockchain.ledger.core.TransactionRequestExtension; | |||
import com.jd.blockchain.utils.Bytes; | |||
public class UserAuthorizeOperationHandle extends AbstractLedgerOperationHandle<UserAuthorizeOperation> { | |||
public UserAuthorizeOperationHandle() { | |||
@@ -49,21 +50,25 @@ public class UserAuthorizeOperationHandle extends AbstractLedgerOperationHandle< | |||
} | |||
} | |||
} | |||
UserRoles ur = urSettings.getUserRoles(urcfg.getUserAddress()); | |||
if (ur == null) { | |||
RolesPolicy policy = urcfg.getPolicy(); | |||
if (policy == null) { | |||
policy = RolesPolicy.UNION; | |||
} | |||
urSettings.addUserRoles(urcfg.getUserAddress(), policy, validRoles); | |||
} else { | |||
ur.addRoles(validRoles); | |||
ur.removeRoles(urcfg.getUnauthorizedRoles()); | |||
for (Bytes address : urcfg.getUserAddresses()) { | |||
UserRoles ur = urSettings.getUserRoles(address); | |||
if (ur == null) { | |||
// 这是新的授权; | |||
RolesPolicy policy = urcfg.getPolicy(); | |||
if (policy == null) { | |||
policy = RolesPolicy.UNION; | |||
} | |||
urSettings.addUserRoles(address, policy, validRoles); | |||
} else { | |||
// 更改之前的授权; | |||
ur.addRoles(validRoles); | |||
ur.removeRoles(urcfg.getUnauthorizedRoles()); | |||
// 如果请求中设置了策略,才进行更新; | |||
RolesPolicy policy = urcfg.getPolicy(); | |||
if (policy != null) { | |||
ur.setPolicy(policy); | |||
// 如果请求中设置了策略,才进行更新; | |||
RolesPolicy policy = urcfg.getPolicy(); | |||
if (policy != null) { | |||
ur.setPolicy(policy); | |||
} | |||
} | |||
} | |||
} | |||
@@ -26,8 +26,8 @@ public interface UserAuthorizeOperation extends Operation { | |||
* | |||
* @return | |||
*/ | |||
@DataField(order = 0, primitiveType = PrimitiveType.BYTES) | |||
Bytes getUserAddress(); | |||
@DataField(order = 0, primitiveType = PrimitiveType.BYTES, list = true) | |||
Bytes[] getUserAddresses(); | |||
/** | |||
* 要更新的多角色权限策略; | |||
@@ -5,8 +5,8 @@ import com.jd.blockchain.utils.Bytes; | |||
public interface UserAuthorize { | |||
UserRolesAuthorizer forUser(BlockchainIdentity userId); | |||
UserRolesAuthorizer forUser(BlockchainIdentity... userId); | |||
UserRolesAuthorizer forUser(Bytes userAddress); | |||
UserRolesAuthorizer forUser(Bytes... userAddress); | |||
} |
@@ -1,9 +1,8 @@ | |||
package com.jd.blockchain.transaction; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
import java.util.LinkedHashMap; | |||
import java.util.LinkedHashSet; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import com.jd.blockchain.binaryproto.DataContractRegistry; | |||
@@ -21,8 +20,8 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe | |||
DataContractRegistry.register(UserRegisterOperation.class); | |||
} | |||
private Map<Bytes, UserRolesAuthorization> userAuthMap = Collections | |||
.synchronizedMap(new LinkedHashMap<Bytes, UserRolesAuthorization>()); | |||
private Set<UserRolesAuthorization> userAuthMap = Collections | |||
.synchronizedSet(new LinkedHashSet<UserRolesAuthorization>()); | |||
public UserAuthorizeOpTemplate() { | |||
} | |||
@@ -32,7 +31,7 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe | |||
@Override | |||
public UserRolesAuthorization[] getUserRolesAuthorizations() { | |||
return ArrayUtils.toArray(userAuthMap.values(), UserRolesAuthorization.class); | |||
return ArrayUtils.toArray(userAuthMap, UserRolesAuthorization.class); | |||
} | |||
@Override | |||
@@ -41,35 +40,33 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe | |||
} | |||
@Override | |||
public UserRolesAuthorizer forUser(Bytes userAddress) { | |||
UserRolesAuthorization userRolesAuth = userAuthMap.get(userAddress); | |||
if (userRolesAuth == null) { | |||
userRolesAuth = new UserRolesAuthorization(userAddress); | |||
userAuthMap.put(userAddress, userRolesAuth); | |||
} | |||
public UserRolesAuthorizer forUser(Bytes... userAddresses) { | |||
UserRolesAuthorization userRolesAuth = new UserRolesAuthorization(userAddresses); | |||
userAuthMap.add(userRolesAuth); | |||
return userRolesAuth; | |||
} | |||
@Override | |||
public UserRolesAuthorizer forUser(BlockchainIdentity userId) { | |||
return forUser(userId.getAddress()); | |||
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) { | |||
Bytes[] addresses = Arrays.stream(userIds).map(p -> p.getAddress()).toArray(Bytes[]::new); | |||
return forUser(addresses); | |||
} | |||
private class UserRolesAuthorization implements UserRolesAuthorizer, UserRolesEntry { | |||
private Bytes userAddress; | |||
private Bytes[] userAddress; | |||
private RolesPolicy policy = RolesPolicy.UNION; | |||
private Set<String> authRoles = new LinkedHashSet<String>(); | |||
private Set<String> unauthRoles = new LinkedHashSet<String>(); | |||
private UserRolesAuthorization(Bytes userAddress) { | |||
private UserRolesAuthorization(Bytes[] userAddress) { | |||
this.userAddress = userAddress; | |||
} | |||
@Override | |||
public Bytes getUserAddress() { | |||
public Bytes[] getUserAddresses() { | |||
return userAddress; | |||
} | |||
@@ -119,13 +116,13 @@ public class UserAuthorizeOpTemplate implements UserAuthorizer, UserAuthorizeOpe | |||
} | |||
@Override | |||
public UserRolesAuthorizer forUser(BlockchainIdentity userId) { | |||
return UserAuthorizeOpTemplate.this.forUser(userId); | |||
public UserRolesAuthorizer forUser(BlockchainIdentity... userIds) { | |||
return UserAuthorizeOpTemplate.this.forUser(userIds); | |||
} | |||
@Override | |||
public UserRolesAuthorizer forUser(Bytes userAddress) { | |||
return UserAuthorizeOpTemplate.this.forUser(userAddress); | |||
public UserRolesAuthorizer forUser(Bytes... userAddresses) { | |||
return UserAuthorizeOpTemplate.this.forUser(userAddresses); | |||
} | |||
} | |||
} |
@@ -65,7 +65,7 @@ com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
crypto.verify-hash=true | |||
#哈希算法; | |||
crypto.hash-algorithm=SHA256; | |||
crypto.hash-algorithm=SHA256 | |||
#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
@@ -20,60 +20,67 @@ import com.jd.blockchain.utils.ConsoleUtils; | |||
/** | |||
* 注册用户 | |||
* | |||
* @author shaozhuguang | |||
* @create 2018/10/18 | |||
* @since 1.0.0 | |||
*/ | |||
public class SDKDemo_RegisterUser { | |||
public static void main(String[] args) { | |||
public static void main(String[] args) { | |||
String GATEWAY_IPADDR = "127.0.0.1"; | |||
int GATEWAY_PORT = 8081; | |||
if (args != null && args.length == 2) { | |||
GATEWAY_IPADDR = args[0]; | |||
GATEWAY_PORT = Integer.parseInt(args[1]); | |||
} | |||
String GATEWAY_IPADDR = "127.0.0.1"; | |||
int GATEWAY_PORT = 8081; | |||
if (args != null && args.length == 2) { | |||
GATEWAY_IPADDR = args[0]; | |||
GATEWAY_PORT = Integer.parseInt(args[1]); | |||
} | |||
// 注册相关class | |||
DataContractRegistry.register(TransactionContent.class); | |||
DataContractRegistry.register(TransactionContentBody.class); | |||
DataContractRegistry.register(TransactionRequest.class); | |||
DataContractRegistry.register(NodeRequest.class); | |||
DataContractRegistry.register(EndpointRequest.class); | |||
DataContractRegistry.register(TransactionResponse.class); | |||
// 注册相关class | |||
DataContractRegistry.register(TransactionContent.class); | |||
DataContractRegistry.register(TransactionContentBody.class); | |||
DataContractRegistry.register(TransactionRequest.class); | |||
DataContractRegistry.register(NodeRequest.class); | |||
DataContractRegistry.register(EndpointRequest.class); | |||
DataContractRegistry.register(TransactionResponse.class); | |||
PrivKey privKey = SDKDemo_Params.privkey1; | |||
PubKey pubKey = SDKDemo_Params.pubKey1; | |||
PrivKey privKey = SDKDemo_Params.privkey1; | |||
PubKey pubKey = SDKDemo_Params.pubKey1; | |||
BlockchainKeypair CLIENT_CERT = new BlockchainKeypair(SDKDemo_Params.pubKey0, SDKDemo_Params.privkey0); | |||
BlockchainKeypair CLIENT_CERT = new BlockchainKeypair(SDKDemo_Params.pubKey0, SDKDemo_Params.privkey0); | |||
boolean SECURE = false; | |||
GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IPADDR, GATEWAY_PORT, SECURE, | |||
CLIENT_CERT); | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
boolean SECURE = false; | |||
GatewayServiceFactory serviceFactory = GatewayServiceFactory.connect(GATEWAY_IPADDR, GATEWAY_PORT, SECURE, | |||
CLIENT_CERT); | |||
BlockchainService service = serviceFactory.getBlockchainService(); | |||
HashDigest[] ledgerHashs = service.getLedgerHashs(); | |||
// 在本地定义注册账号的 TX; | |||
TransactionTemplate txTemp = service.newTransaction(ledgerHashs[0]); | |||
HashDigest[] ledgerHashs = service.getLedgerHashs(); | |||
// 在本地定义注册账号的 TX; | |||
TransactionTemplate txTemp = service.newTransaction(ledgerHashs[0]); | |||
//existed signer | |||
AsymmetricKeypair keyPair = new BlockchainKeypair(pubKey, privKey); | |||
// existed signer | |||
AsymmetricKeypair keyPair = new BlockchainKeypair(pubKey, privKey); | |||
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); | |||
BlockchainKeypair user = BlockchainKeyGenerator.getInstance().generate(); | |||
// 注册 | |||
txTemp.users().register(user.getIdentity()); | |||
// 注册 | |||
txTemp.users().register(user.getIdentity()); | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 定义角色权限; | |||
txTemp.security().roles().configure("MANAGER") | |||
.enable(LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT) | |||
.enable(TransactionPermission.CONTRACT_OPERATION); | |||
txTemp.security().authorziations().forUser(user.getIdentity()).authorize("MANAGER"); | |||
// 使用私钥进行签名; | |||
prepTx.sign(keyPair); | |||
// TX 准备就绪; | |||
PreparedTransaction prepTx = txTemp.prepare(); | |||
// 提交交易; | |||
TransactionResponse transactionResponse = prepTx.commit(); | |||
// 使用私钥进行签名; | |||
prepTx.sign(keyPair); | |||
ConsoleUtils.info("register user complete, result is [%s]", transactionResponse.isSuccess()); | |||
} | |||
// 提交交易; | |||
TransactionResponse transactionResponse = prepTx.commit(); | |||
ConsoleUtils.info("register user complete, result is [%s]", transactionResponse.isSuccess()); | |||
} | |||
} |
@@ -8,6 +8,48 @@ ledger.name=TEST-LEDGER | |||
#声明的账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区 | |||
created-time=2019-08-01 14:26:58.069+0800 | |||
#----------------------------------------------- | |||
# 初始的角色名称列表;可选项; | |||
# 角色名称不区分大小写,最长不超过20个字符;多个角色名称之间用半角的逗点“,”分隔; | |||
# 系统会预置一个默认角色“DEFAULT”,所有未指定角色的用户都以赋予该角色的权限;若初始化时未配置默认角色的权限,则为默认角色分配所有权限; | |||
# | |||
# 注:如果声明了角色,但未声明角色对应的权限清单,这会忽略该角色的初始化; | |||
# | |||
security.roles=DEFAULT, ADMIN, MANAGER, GUEST | |||
# 赋予角色的账本权限清单;可选项; | |||
# 可选的权限如下; | |||
# AUTHORIZE_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, | |||
# REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, | |||
# SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT, | |||
# APPROVE_TX, CONSENSUS_TX | |||
# 多项权限之间用逗点“,”分隔; | |||
# | |||
security.role.DEFAULT.ledger-privileges=REGISTER_USER, REGISTER_DATA_ACCOUNT | |||
# 赋予角色的交易权限清单;可选项; | |||
# 可选的权限如下; | |||
# DIRECT_OPERATION, CONTRACT_OPERATION | |||
# 多项权限之间用逗点“,”分隔; | |||
# | |||
security.role.DEFAULT.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION | |||
# 其它角色的配置示例; | |||
# 系统管理员角色:只能操作全局性的参数配置和用户注册,只能执行直接操作指令; | |||
security.role.ADMIN.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, REGISTER_USER | |||
security.role.ADMIN.tx-privileges=DIRECT_OPERATION | |||
# 业务主管角色:只能够执行账本数据相关的操作,包括注册用户、注册数据账户、注册合约、升级合约、写入数据等;能够执行直接操作指令和调用合约; | |||
security.role.MANAGER.ledger-privileges=CONFIGURE_ROLES, AUTHORIZE_USER_ROLES, REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT, | |||
security.role.MANAGER.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION | |||
# 访客角色:不具备任何的账本权限,只有数据读取的操作;也只能够通过调用合约来读取数据; | |||
security.role.GUEST.ledger-privileges= | |||
security.role.GUEST.tx-privileges=CONTRACT_OPERATION | |||
#----------------------------------------------- | |||
#共识服务提供者;必须; | |||
consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider | |||
@@ -18,6 +60,12 @@ consensus.conf=classpath:bftsmart.config | |||
crypto.service-providers=com.jd.blockchain.crypto.service.classic.ClassicCryptoService, \ | |||
com.jd.blockchain.crypto.service.sm.SMCryptoService | |||
#从存储中加载账本数据时,是否校验哈希;可选; | |||
crypto.verify-hash=true | |||
#哈希算法; | |||
crypto.hash-algorithm=SHA256 | |||
#参与方的个数,后续以 cons_parti.id 分别标识每一个参与方的配置; | |||
cons_parti.count=4 | |||
@@ -27,6 +75,10 @@ cons_parti.0.name=jd.com | |||
cons_parti.0.pubkey-path=keys/jd-com.pub | |||
#第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9 | |||
#第0个参与方的角色清单;可选项; | |||
cons_parti.0.roles=ADMIN, MANAGER | |||
#第0个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
cons_parti.0.roles-policy=UNION | |||
#第0个参与方的共识服务的主机地址; | |||
cons_parti.0.consensus.host=127.0.0.1 | |||
#第0个参与方的共识服务的端口; | |||
@@ -46,6 +98,10 @@ cons_parti.1.name=at.com | |||
cons_parti.1.pubkey-path=keys/at-com.pub | |||
#第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX | |||
#第1个参与方的角色清单;可选项; | |||
cons_parti.1.roles=MANAGER | |||
#第1个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
cons_parti.1.roles-policy=UNION | |||
#第1个参与方的共识服务的主机地址; | |||
cons_parti.1.consensus.host=127.0.0.1 | |||
#第1个参与方的共识服务的端口; | |||
@@ -65,6 +121,10 @@ cons_parti.2.name=bt.com | |||
cons_parti.2.pubkey-path=keys/bt-com.pub | |||
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.2.pubkey=3snPdw7i7PZi6TStiyc6mzjprnNhgs2atSGNS8wPYzhbKaUWGFJt7x | |||
#第2个参与方的角色清单;可选项; | |||
cons_parti.2.roles=MANAGER | |||
#第2个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
cons_parti.2.roles-policy=UNION | |||
#第2个参与方的共识服务的主机地址; | |||
cons_parti.2.consensus.host=127.0.0.1 | |||
#第2个参与方的共识服务的端口; | |||
@@ -84,6 +144,10 @@ cons_parti.3.name=xt.com | |||
cons_parti.3.pubkey-path=keys/xt-com.pub | |||
#第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数; | |||
cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk | |||
#第3个参与方的角色清单;可选项; | |||
cons_parti.3.roles=GUEST | |||
#第3个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项; | |||
cons_parti.3.roles-policy=INTERSECT | |||
#第3个参与方的共识服务的主机地址; | |||
cons_parti.3.consensus.host=127.0.0.1 | |||
#第3个参与方的共识服务的端口; | |||
@@ -9,6 +9,7 @@ import java.util.*; | |||
*/ | |||
public abstract class ArrayUtils { | |||
private ArrayUtils() { | |||
} | |||
public static <T> T[] singleton(T obj, Class<T> clazz) { | |||