Explorar o código

优化权限控制逻辑

zhouhao %!s(int64=6) %!d(string=hai) anos
pai
achega
b65cd633c1

+ 2 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/Permission.java

@@ -85,6 +85,8 @@ public interface Permission extends Serializable {
      */
     String getId();
 
+    String getName();
+
     /**
      * 用户对此权限的可操作事件(按钮)
      * <p>

+ 2 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimplePermission.java

@@ -22,6 +22,8 @@ public class SimplePermission implements Permission {
 
     private String id;
 
+    private String name;
+
     private Set<String> actions;
 
     private Set<DataAccessConfig> dataAccesses;

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/builder/SimpleAuthenticationBuilder.java

@@ -86,7 +86,7 @@ public class SimpleAuthenticationBuilder implements AuthenticationBuilder {
             JSONObject jsonObject = jsonArray.getJSONObject(i);
             SimplePermission permission = new SimplePermission();
             permission.setId(jsonObject.getString("id"));
-
+            permission.setName(jsonObject.getString("name"));
             JSONArray actions = jsonObject.getJSONArray("actions");
             if (actions != null) {
                 permission.setActions(new HashSet<>(actions.toJavaList(String.class)));

+ 33 - 31
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java

@@ -89,48 +89,50 @@ public class DefaultAopMethodAuthorizeDefinitionParser implements AopMethodAutho
             cache.put(key, EmptyAuthorizeDefinition.instance);
             return null;
         }
-        DefaultBasicAuthorizeDefinition authorizeDefinition = new DefaultBasicAuthorizeDefinition();
-        authorizeDefinition.setTargetClass(target);
-        authorizeDefinition.setTargetMethod(method);
-        if (methodAuth == null || methodAuth.merge()) {
-            authorizeDefinition.put(classAuth);
-        }
+        synchronized (cache) {
+            DefaultBasicAuthorizeDefinition authorizeDefinition = new DefaultBasicAuthorizeDefinition();
+            authorizeDefinition.setTargetClass(target);
+            authorizeDefinition.setTargetMethod(method);
+            if (methodAuth == null || methodAuth.merge()) {
+                authorizeDefinition.put(classAuth);
+            }
 
-        authorizeDefinition.put(methodAuth);
+            authorizeDefinition.put(methodAuth);
 
-        authorizeDefinition.put(expression);
+            authorizeDefinition.put(expression);
 
-        authorizeDefinition.put(classDataAccess);
+            authorizeDefinition.put(classDataAccess);
 
-        authorizeDefinition.put(methodDataAccess);
+            authorizeDefinition.put(methodDataAccess);
 
-        if (authorizeDefinition.getPermissionDescription().length == 0) {
-            if (classAuth != null) {
-                authorizeDefinition.put(classAuth.dataAccess());
-                String[] desc = classAuth.description();
-                if (desc.length > 0) {
-                    authorizeDefinition.setPermissionDescription(desc);
+            if (authorizeDefinition.getPermissionDescription().length == 0) {
+                if (classAuth != null) {
+                    authorizeDefinition.put(classAuth.dataAccess());
+                    String[] desc = classAuth.description();
+                    if (desc.length > 0) {
+                        authorizeDefinition.setPermissionDescription(desc);
+                    }
                 }
             }
-        }
 
-        if (authorizeDefinition.getActionDescription().length == 0) {
-            if (methodAuth != null) {
-                if (methodAuth.description().length != 0) {
-                    authorizeDefinition.setActionDescription(methodAuth.description());
+            if (authorizeDefinition.getActionDescription().length == 0) {
+                if (methodAuth != null) {
+                    if (methodAuth.description().length != 0) {
+                        authorizeDefinition.setActionDescription(methodAuth.description());
+                    }
                 }
             }
-        }
 
-        log.info("parsed authorizeDefinition {}.{} => {}.{} permission:{} actions:{}",
-                target.getSimpleName(),
-                method.getName(),
-                authorizeDefinition.getPermissionDescription(),
-                authorizeDefinition.getActionDescription(),
-                authorizeDefinition.getPermissions(),
-                authorizeDefinition.getActions());
-        cache.put(key, authorizeDefinition);
-        return authorizeDefinition;
+            log.info("parsed authorizeDefinition {}.{} => {}.{} permission:{} actions:{}",
+                    target.getSimpleName(),
+                    method.getName(),
+                    authorizeDefinition.getPermissionDescription(),
+                    authorizeDefinition.getActionDescription(),
+                    authorizeDefinition.getPermissions(),
+                    authorizeDefinition.getActions());
+            cache.put(key, authorizeDefinition);
+            return authorizeDefinition;
+        }
     }
 
     public CacheKey buildCacheKey(Class target, Method method) {

+ 3 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationProperties.java

@@ -65,6 +65,8 @@ public class EmbedAuthenticationProperties {
     public static class PermissionInfo {
         private String id;
 
+        private String name;
+
         private Set<String> actions = new HashSet<>();
 
         private List<Map<String, Object>> dataAccesses = new ArrayList<>();
@@ -85,6 +87,7 @@ public class EmbedAuthenticationProperties {
                 .map(info -> {
                     SimplePermission permission = new SimplePermission();
                     permission.setId(info.getId());
+                    permission.setName(info.getName());
                     permission.setActions(info.getActions());
                     permission.setDataAccesses(info.getDataAccesses()
                             .stream().map(conf -> factory.create()

+ 3 - 5
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java

@@ -160,12 +160,10 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         // 控制权限
         if (!definition.getPermissions().isEmpty()) {
             if (logger.isInfoEnabled()) {
-                logger.info("do permission access handle : permissions{}({}),actions{} ,definition:{}.{} ({})",
+                logger.info("执行权限控制:权限{}({}),操作{}.",
                         definition.getPermissionDescription(),
-                        permissionsDef, actionsDef
-                        , definition.getPermissions(),
-                        definition.getActions(),
-                        definition.getLogical());
+                        permissionsDef,
+                        actionsDef);
             }
             List<Permission> permissions = authentication.getPermissions().stream()
                     .filter(permission -> {

+ 2 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/entity/authorization/ParentPermission.java

@@ -19,4 +19,6 @@ public class ParentPermission implements Entity {
     private String permission;
 
     private Set<String> actions;
+
+    private Set<String> preActions;
 }

+ 76 - 19
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-local/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorizationSettingService.java

@@ -16,6 +16,8 @@
  */
 package org.hswebframework.web.service.authorization.simple;
 
+import lombok.Getter;
+import lombok.Setter;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationInitializeService;
 import org.hswebframework.web.authorization.Permission;
@@ -24,6 +26,7 @@ import org.hswebframework.web.authorization.simple.SimpleAuthentication;
 import org.hswebframework.web.authorization.simple.SimplePermission;
 import org.hswebframework.web.authorization.simple.SimpleRole;
 import org.hswebframework.web.authorization.simple.SimpleUser;
+import org.hswebframework.web.commons.entity.DataStatus;
 import org.hswebframework.web.commons.entity.TreeSupportEntity;
 import org.hswebframework.web.dao.authorization.AuthorizationSettingDao;
 import org.hswebframework.web.dao.authorization.AuthorizationSettingDetailDao;
@@ -358,6 +361,26 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
         return initPermission(detailList);
     }
 
+    @Getter
+    @Setter
+    static class ParentPermissionDetail extends ParentPermission {
+        private String sourcePermission;
+
+        public static Stream<ParentPermissionDetail> of(PermissionEntity entity) {
+            return entity.getParents()
+                    .stream()
+                    .filter(Objects::nonNull)
+                    .map(parent -> {
+                        ParentPermissionDetail permissionDetail = new ParentPermissionDetail();
+                        permissionDetail.setActions(parent.getActions());
+                        permissionDetail.setSourcePermission(entity.getId());
+                        permissionDetail.setPreActions(parent.getPreActions());
+                        permissionDetail.setPermission(parent.getPermission());
+                        return permissionDetail;
+                    });
+        }
+    }
+
     private List<Permission> initPermission(List<AuthorizationSettingDetailEntity> detailList) {
         //权限id集合
         List<String> permissionIds = detailList.stream()
@@ -406,15 +429,14 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
                 .collect(Collectors.groupingBy(AuthorizationSettingDetailEntity::getPermissionId));
 
         List<Permission> permissions = new ArrayList<>();
-        //获取关联的权限信息
-        Map<String, List<ParentPermission>> parentsPermissions = permissionEntityCache.values().stream()
-                .map(PermissionEntity::getParents)
-                .filter(Objects::nonNull)
-                .flatMap(Collection::stream)
-                .collect(Collectors.groupingBy(ParentPermission::getPermission));
 
         settings.forEach((permissionId, details) -> {
+            PermissionEntity entity = permissionEntityCache.get(permissionId);
+            if (entity == null || !DataStatus.STATUS_ENABLED.equals(entity.getStatus())) {
+                return;
+            }
             SimplePermission permission = new SimplePermission();
+            permission.setName(entity.getName());
             permission.setId(permissionId);
             Set<String> actions = new HashSet<>();
             Set<DataAccessConfig> dataAccessConfigs = new HashSet<>();
@@ -427,36 +449,68 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
                     dataAccessConfigs.clear();
                 }
                 // actions
-                if (null != detail.getActions()) {
+                if (isNotEmpty(detail.getActions())) {
                     actions.addAll(detail.getActions());
                 }
                 // 数据权限控制配置
-                if (null != detail.getDataAccesses()) {
+                if (isNotEmpty(detail.getDataAccesses())) {
                     dataAccessConfigs.addAll(detail.getDataAccesses()
                             .stream()
                             .map(dataAccessFactory::create)
                             .collect(Collectors.toSet()));
                 }
             }
-            //是否有其他权限关联了此权限
-            List<ParentPermission> parents = parentsPermissions.get(permissionId);
-            if (parents != null) {
-                actions.addAll(parents.stream()
-                        .map(ParentPermission::getActions)
-                        .filter(Objects::nonNull)
-                        .flatMap(Collection::stream)
-                        .collect(Collectors.toSet()));
-                parentsPermissions.remove(permissionId);
-            }
+
             permission.setActions(actions);
             permission.setDataAccesses(dataAccessConfigs);
             permissions.add(permission);
         });
 
-        //关联权限
+        /*=============================进行关联权限处理============================================*/
+        Map<String, Permission> permissionCache = permissions.stream()
+                .collect(Collectors.toMap(Permission::getId, Function.identity()));
+
+        //获取关联的权限信息
+        Map<String, List<ParentPermissionDetail>> parentsPermissions = permissionEntityCache
+                .values()
+                .stream()
+                .flatMap(ParentPermissionDetail::of)
+                .collect(Collectors.groupingBy(ParentPermission::getPermission));
+
+        for (Permission permission : permissions) {
+            //有其他权限关联了此权限
+            List<ParentPermissionDetail> parents = parentsPermissions.get(permission.getId());
+            if (parents != null) {
+                //添加action
+                permission.getActions()
+                        .addAll(parents.stream()
+                                .filter(parent -> {
+                                    if (CollectionUtils.isEmpty(parent.getActions())) {
+                                        return false;
+                                    }
+                                    if (CollectionUtils.isEmpty(parent.getPreActions())) {
+                                        return true;
+                                    }
+                                    //判断是否满足关联权限的条件
+                                    Permission source = permissionCache.get(parent.getSourcePermission());
+                                    return source != null && parent.getPreActions().containsAll(source.getActions());
+                                })
+                                .map(ParentPermission::getActions)
+                                .flatMap(Collection::stream)
+                                .collect(Collectors.toSet()));
+                //删除被合并的权限配置
+                parentsPermissions.remove(permission.getId());
+            }
+        }
+        //没有赋予被关联的权限时,直接关联权限
         parentsPermissions.forEach((per, all) -> {
+            PermissionEntity entity = permissionEntityCache.get(permissionId);
+            if (entity == null || !DataStatus.STATUS_ENABLED.equals(entity.getStatus())) {
+                return;
+            }
             SimplePermission permission = new SimplePermission();
             permission.setId(per);
+            permission.setName(entity.getName());
             permission.setActions(all.stream()
                     .map(ParentPermission::getActions)
                     .filter(Objects::nonNull)
@@ -464,6 +518,9 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
                     .collect(Collectors.toSet()));
             permissions.add(permission);
         });
+        parentsPermissions.clear();
+        permissionCache.clear();
+
         return permissions;
     }