Aithosa opened a new issue, #4722: URL: https://github.com/apache/servicecomb-java-chassis/issues/4722
### Problem this feature would solve ## 需要确认的用法 以[java-chassis-samples/trust-sample](https://github.com/apache/servicecomb-samples/tree/master/java-chassis-samples/trust-sample) 为例。 `3.x.x`版本,要想启用该功能,服务端需要配置: ```yaml servicecomb: publicKey: accessControl: # handler-publickey-auth 的开关 enabled: true # excludePathPatterns: '/health,/schema/contents' black: list01: ## property, fixed value category: property ## property name, e.g. serviceName, appId, environment, alias, version and so on, ## also support key in properties. propertyName: serviceName # property value match expression. # if propertyName is serviceName # only supports prefix match and postfix match and exactly match. # e.g. hacker*, *hacker, hacker rule: hacker white: list02: category: property propertyName: serviceName rule: cust* ``` 客户端需要配置 ```yaml servicecomb: publicKey: accessControl: enabled: true ``` `3.x.x`版本都采用Filter之后,`servicecomb.handler`作为前缀的配置不在生效, 并且不再需要类似下面这样的配置来控制开关了: ```yaml servicecomb: handler: chain: Consumer: default: loadbalance,auth-consumer Provider: default: auth-provider ``` 根据`org.apache.servicecomb.core.filter.AbstractFilter`,`ProviderAuthFilter`和`ConsumerAuthFilter`的开关配置是: ``` servicecomb.filter.provider-public-key.trust-sample.store.enabled servicecomb.filter.provider-public-key.trust-sample.store.order servicecomb.filter.consumer-public-key.trust-sample.store.enabled servicecomb.filter.consumer-public-key.trust-sample.store.order ``` 不过默认是开启的。 - 如果customer配置了`servicecomb.publicKey.accessControl.enabled`,但是store不允许customer访问,会因为验证失败而报错(401)。 - 如果customer没有配置或者设置的false,则会因为请求不携带token调用而返回失败(401)。 ## 使用中遇到的问题 ### consumer无法调用provider 按以上配置启动`store`之后,再启动`customer`有一定几率无法调用`store`的接口。 debug`store`后发现,在`org.apache.servicecomb.authentication.provider.ProviderTokenManager`中,客户端调用接口时传过来了`token`,但`isValidToken(rsaToken)`**有几率会不通过**。 > 通过的几率较小,大部分尝试都无法验证token,情况不稳定,能通过说明配置应该是没问题的 > 每次运行前都会clean然后在编译,依然有时可以有时不行 ```java public boolean valid(String token) { try { RSAAuthenticationToken rsaToken = RSAAuthenticationToken.fromStr(token); if (null == rsaToken) { LOGGER.error("token format is error, perhaps you need to set auth handler at consumer"); return false; } if (tokenExpired(rsaToken)) { LOGGER.error("token is expired"); return false; } if (validatedToken.asMap().containsKey(rsaToken)) { return accessController.isAllowed(microserviceInstanceCache.getOrCreate( rsaToken.getServiceId(), rsaToken.getInstanceId())); } // isValidToken()这里有几率会出问题,publicKey会验证失败 if (isValidToken(rsaToken) && !tokenExpired(rsaToken)) { validatedToken.put(rsaToken, true); return accessController.isAllowed(microserviceInstanceCache.getOrCreate( rsaToken.getServiceId(), rsaToken.getInstanceId())); } return false; } catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | SignatureException e) { LOGGER.error("verify error", e); return false; } } ``` ## 建议和想法 `servicecomb.publicKey.accessControl.includePathPatterns`和`servicecomb.publicKey.accessControl.excludePathPatterns`判断时用的path是从`invocation.getOperationMeta().getOperationPath()`里获取的。 `/scb/management`下的路径要想设置到excludePathPatterns中,如`/health`和`/schema/contents`两个都要放进去,而不能用共同的前缀`/scb/management`。 另外,这里的功能是阻止其他服务调用本服务,实际上请求还是已经来到了本服务中,只不过没来得及走到具体的业务处理流程中,感觉有点奇怪。 ### Describe the solution _No response_ ### Alternatives considered _No response_ ### Additional Context _No response_ -- 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]
