sunxi92 commented on issue #4688:
URL: https://github.com/apache/rocketmq/issues/4688#issuecomment-1204667296
> This design requires updating rocketmq-client, which might bring cost for
users to update rocketmq-client. I've some suggestions:
>
> 1. `accessKey` should be defined as a globally unique string, so that
complexity is reduced and users with older versions of rocketmq-client may
adopt this feature.
> Some uniqueness check of `accessKey` should be added in ACL mqadmin
command to keep `accessKey` globally unique with best effort.
> 2. One `accessKey` can only be granted permissions to access resources in
the same namespace.
> 3. Separate presentation with storage of namespace in ACL module.
`{namespace}%{resource}` is just a presentation way of resources in a
namespace. For the definition of `account` data structure, a new field should
be added to store namespace. When checking permissions, resources defined in
ACL account are converted as `{namespace}%{resource}`.
>
> In that way, the ACL config file would like this:
>
> ```yaml
> globalWhiteRemoteAddresses:
> - 10.10.103.*
> - 192.168.0.*
> accounts:
> - accessKey: RocketMQ # accessKey is globally unique
> secretKey: 12345678
> namespace: namespace1 # add namespace field in acount
> whiteRemoteAddress:
> admin: false
> defaultTopicPerm: DENY
> defaultGroupPerm: SUB
> # All topics below are in namespace1
> topicPerms:
> - topicA=DENY
> - topicB=PUB|SUB
> - topicC=SUB
> # All groups below are in namespace1
> groupPerms:
> - groupA=DENY
> - groupB=PUB|SUB
> - groupC=SUB
> - accessKey: rocketmq2 # rocketmq2 is in a 'default' namespace
> secretKey: 12345678
> whiteRemoteAddress: 192.168.1.*
> admin: true
> ```
It is true that there is a little consideration to the client upgrades. So I
adjust the design. The details are as follows:
1.Clients don't need to be upgraded, they can use this feature as follows:
`
public class ProducerAclWithNamespace {
public static final String NAMESPACE = "n";
public static final String PRODUCER_GROUP = "producerGroup";
public static final String DEFAULT_NAMESRVADDR = "127.0.0.1:9876";
public static final int MESSAGE_COUNT = 100;
public static final String TOPIC = "topicB";
public static final String TAG = "tagTest";
private static final String ACL_ACCESS_KEY = "RocketMQ";
private static final String ACL_SECRET_KEY = "12345678";
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer(NAMESPACE,
PRODUCER_GROUP, getAclRPCHook());
producer.setNamesrvAddr(DEFAULT_NAMESRVADDR);
producer.start();
for (int i = 0; i < MESSAGE_COUNT; i++) {
Message message = new Message(TOPIC, TAG, "Hello
world".getBytes());
try {
SendResult result = producer.send(message);
System.out.printf("Topic:%s send success, misId is:%s%n",
message.getTopic(), result.getMsgId());
} catch (Exception e) {
e.printStackTrace();
}
}
}
static RPCHook getAclRPCHook() {
return new AclClientRPCHook(new
SessionCredentials(ACL_ACCESS_KEY,ACL_SECRET_KEY));
}
}
public class ConsumerAclWithNamespace {
public static final String NAMESPACE = "n";
public static final String CONSUMER_GROUP = "groupB";
public static final String DEFAULT_NAMESRVADDR = "127.0.0.1:9876";
public static final String TOPIC = "topicB";
private static final String ACL_ACCESS_KEY = "RocketMQ";
private static final String ACL_SECRET_KEY = "12345678";
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer defaultMQPushConsumer = new
DefaultMQPushConsumer(NAMESPACE, CONSUMER_GROUP, getAclRPCHook());
defaultMQPushConsumer.setNamesrvAddr(DEFAULT_NAMESRVADDR);
defaultMQPushConsumer.subscribe(TOPIC, "*");
defaultMQPushConsumer.registerMessageListener((MessageListenerConcurrently)
(msgs, context) -> {
msgs.forEach(msg -> System.out.printf("Msg topic is:%s, MsgId
is:%s, reconsumeTimes is:%s%n", msg.getTopic(), msg.getMsgId(),
msg.getReconsumeTimes()));
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
defaultMQPushConsumer.start();
}
static RPCHook getAclRPCHook() {
return new AclClientRPCHook(new
SessionCredentials(ACL_ACCESS_KEY,ACL_SECRET_KEY));
}
}
`
2."namesppace%ak" is globally unique and the config of acl is modified as
follows:
`
globalWhiteRemoteAddresses:
- 10.10.103.*
- 192.168.0.*
accounts:
- accessKey: namespace1%RocketMQ
secretKey: 12345678
whiteRemoteAddress:
admin: false
defaultTopicPerm: DENY
defaultGroupPerm: SUB
topicPerms:
- namespace1%topicA=DENY
- namespace1%topicB=PUB|SUB
- namespace1%topicC=SUB
groupPerms:
- namespace1%groupA=DENY
- namespace1%groupB=PUB|SUB
- namespace1%groupC=SUB
- accessKey: rocketmq2
secretKey: 12345678
whiteRemoteAddress: 192.168.1.*
admin: true
`
3.To support this feature, the code in acl module needs to be modified as
follows
When broker parse the request from client, the broker needs to get the
namespace from the request. When namespace is not null, broker can set the
accesskey
4.ACL mqadmin commands also need to be modified, updateAclConfig and
deleteAccessConfig should add a optional parameter called namespace to support
namespace
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]