You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In order to better expand the permission management capabilities of Apollo Portal in the future, the existing Namespace-related permission management has been sorted out and integrated.
@PutMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", consumes = {"application/json"})
publicResponseEntity<Void> update(@PathVariableStringappId, @PathVariableStringnamespaceName,
@RequestBodyNamespaceSyncModelmodel) {
checkModel(!model.isInvalid() && model.syncToNamespacesValid(appId, namespaceName));
booleanhasPermission = permissionValidator.hasModifyNamespacePermission(appId, namespaceName);
EnvenvNoPermission = null;
// if uses has ModifyNamespace permission then he has permissionif (!hasPermission) {
// else check if user has every env's ModifyNamespace permissionhasPermission = true;
for (NamespaceIdentifiernamespaceIdentifier : model.getSyncToNamespaces()) {
// once user has not one of the env's ModifyNamespace permission, then break the loophasPermission &= permissionValidator.hasModifyNamespacePermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getNamespaceName(), namespaceIdentifier.getEnv().toString())
|| permissionValidator.hasModifyClusterPermission(namespaceIdentifier.getAppId(), namespaceIdentifier.getEnv().toString(), namespaceIdentifier.getClusterName());
if (!hasPermission) {
envNoPermission = namespaceIdentifier.getEnv();
break;
}
}
if (hasPermission) {
configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems());
returnResponseEntity.status(HttpStatus.OK).build();
}
thrownewAccessDeniedException(String.format("You don't have the permission to modify namespace: %s", noPermissionNamespace));
}
原本逻辑:
校验是否有 AppId → Namespace 权限,如有则直接放行
if 没有,则分别校验对每个Namespace的 AppId + Env → Namespace 权限
if 其中一个Namespace没有权限,则抛出无权限异常
改动逻辑:
取消掉第一步校验,直接对每个Namespace调用统一的接口进行权限校验
After:
@PutMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", consumes = {"application/json"})
publicResponseEntity<Void> update(@PathVariableStringappId, @PathVariableStringnamespaceName,
@RequestBodyNamespaceSyncModelmodel) {
checkModel(!model.isInvalid() && model.syncToNamespacesValid(appId, namespaceName));
NamespaceIdentifiernoPermissionNamespace = null;
// check if user has every namespace's ModifyNamespace permissionbooleanhasPermission = true;
for (NamespaceIdentifiernamespaceIdentifier : model.getSyncToNamespaces()) {
// once user has not one of the namespace's ModifyNamespace permission, then break the loophasPermission = permissionValidator.hasModifyNamespacePermission(
namespaceIdentifier.getAppId(),
namespaceIdentifier.getEnv().getName(),
namespaceIdentifier.getClusterName(),
namespaceIdentifier.getNamespaceName()
);
if (!hasPermission) {
noPermissionNamespace = namespaceIdentifier;
break;
}
}
if (hasPermission) {
configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems());
returnResponseEntity.status(HttpStatus.OK).build();
}
thrownewAccessDeniedException(String.format("You don't have the permission to modify namespace: %s", noPermissionNamespace));
}
Is your feature request related to a problem? Please describe.
According to #5301
In order to better expand the permission management capabilities of Apollo Portal in the future, the existing Namespace-related permission management has been sorted out and integrated.
Describe the solution you'd like
Namespace权限模型梳理
前三个字段是限定了一个权限scope,范围从App到Env再到Cluster三级维度。
因为是针对Namespace的权限,所以Namespace字段是比较不同的,为空时代表指向当前scope下所有Namespace,否则指向所有名为传入值的Namespace。
考虑到向前兼容,兼容原有的 PermissionType ,原有的
AppId → Namespace
和AppId + Env → Namespace
两种权限模型的 PermissionType 都为ModifyNamespace/ReleaseNamespace
,包括原有的TargetId格式,都是不能修改的。Apollo的权限校验方式是这样的:
原有的两种权限模型的PermissionType是一样的,而在匹配需要的Permission的时候是要用Type+TargetId的,TargetId在Apollo中是用字符串拼接的方式生成的,中间用“+”号隔开,举个例子:
ModifyNamespace
-test20251228+application
ModifyNamespace
-test20251228+application+LOCAL
因为参数数量分别是两个和三个,当Type相同,TargetId不会起歧义,指向错误的目标。
但是后续的权限模型的Type不能再继续沿用这个TypeName了,因为还有其他三个参数的权限模型存在,比如说
AppId + Env + Cluster → *
这个模型。TargetId可能是
test20251228+LOCAL+PRO
,也就是**“LOCAL环境下的PRO集群”,这种情况下就会和“PRO环境下所有名为LOCAL的Namespace”**产生二义性,这在权限系统中是危险的,可能会出现越权行为。因此除了现有的两种存量权限模型,后续新增的Namespace权限模型,都需要有自己独特的PermissionType,以避免TargetId出现二义性问题。
整体架构
改动点
1. Annotation 入口
全部改为四个入参的方法
2. Api 入口
同步Namespace能力接口
原本逻辑:
改动逻辑:
思考 & 风险点 & 改进点
这样每次进行一次权限校验,可能会涉及到多次数据库IO,可能会成为性能瓶颈,后续可以改为一次查询,或引入一些缓存方案来解决。
The text was updated successfully, but these errors were encountered: