xiaozongyang opened a new issue #3271:
URL: https://github.com/apache/rocketmq/issues/3271


   **BUG REPORT**
   
   1. Please describe the issue you observed:
   
   - What did you do (The steps to reproduce)?
       1. define a custom RPCHook named MetricRPCHook, e.g, a metric 
instrumentation RPCHook 
       2. add an `extField` in RPCHook, shown as following code
           ```code
               public void doBeforeRequest(String remoteAddr, RemotingCommand 
request) {
                    request.addExtField("startTimeMills", 
Long.toString(System.currentTimeMills()));
               }
           ```
       3. composite `MetricRPCHook` and `AclClientRPCHook` into one RPCHook 
like this
          ``` java
              public void doBeforeRequest(String remoteAddr, RemotingCommand 
request) {
                   metricHook.doBeforeRequest(remoteAddr, request);
                   aclHook.doBeforeRequest(remoteAddr, request);
               }
          ```
   
   - What did you expect to see?
      - producer/consumer can produce/consume message with this 
compositedRPCHook correctly
   - What did you see instead?
      - an authentication error with following message
         ```java
         org.apache.rocketmq.client.exception.MQBrokerException: CODE: 1 DESC: 
com.aliyun.openservices.ons.api.impl.authority.exception.AuthenticationException:
 signature validate failed.-2 Signature not match!, validate=false, 
akDisabled=false, whiteList=true, 
com.alibaba.ons.open.auth.service.AuthServiceImpl.aliyunSignatureValidate(AuthServiceImpl.java:259)
 For more information, please visit the url, 
http://rocketmq.apache.org/docs/faq/ at
         ```
   2. Please tell us about your environment:
       - `OS`:  `macOS Big Sur 11.2.3`
       - `Java version`: `1.8.0_192`
       - `rocketmq-client version`: `4.5.2`
   
   3. Other information (e.g. detailed explanation, logs, related issues, 
suggestions on how to fix, etc):
      
   Since secret signature calculations are implemented differently in 
[`AclClientRPCHook#parseRequestContent`](https://github.com/apache/rocketmq/blob/d63678dc507e5d341a125f95a99859d2fdafa408/acl/src/main/java/org/apache/rocketmq/acl/common/AclClientRPCHook.java#L70)
 and 
[`PlainAccessValidator#parse`](https://github.com/apache/rocketmq/blob/d63678dc507e5d341a125f95a99859d2fdafa408/acl/src/main/java/org/apache/rocketmq/acl/plain/PlainAccessValidator.java#L125)
            1. when we sign signature in `AclClientRPCHook` we don't try to 
read any `extField` from `request`
            2. when we sign signature in `PlainAccessValidator` we read all 
`extField`s from `request` expect the key `Signature`
   So, if we add any `extField` to `request` we will fall into the 
authentication error described above.
   
   One possible fix to this bug may be following code snippet,
   
   ```java
       public void doBeforeRequest(String remoteAddr, RemotingCommand request) {
           byte[] total = AclUtils.combineRequestContent(request, 
getAclHeaders(request));
   
           String signature = AclUtils.calSignature(total, 
sessionCredentials.getSecretKey());
           request.addExtField(SIGNATURE, signature);
           request.addExtField(ACCESS_KEY, sessionCredentials.getAccessKey());
   
           // The SecurityToken value is uneccessary,user can choose this one.
           if (getSessionCredentials().getSecurityToken() != null) {
               request.addExtField(SECURITY_TOKEN, 
sessionCredentials.getSecurityToken());
           }
       }
   
       private SortedMap<String, String> getAclHeaders(RemotingCommand request) 
{
           SortedMap<String, String> fieldsMap = parseRequestContent(request, 
getSessionCredentials().getAccessKey(), sessionCredentials.getSecurityToken());
           request.getExtFields().forEach((k, v) -> {
               if (StringUtils.equals(ACCESS_KEY, k)) {
                   return;
               }
               if (StringUtils.equals(SIGNATURE, k)) {
                   return;
               }
               fieldsMap.put(k, v);
           });
           return fieldsMap;
       }
   
   ```


-- 
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]


Reply via email to