Selaa lähdekoodia

优化数据权限

zhouhao 6 vuotta sitten
vanhempi
commit
fa546389f8
9 muutettua tiedostoa jossa 235 lisäystä ja 91 poistoa
  1. 20 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/UserAttachEntity.java
  2. 5 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresDataAccess.java
  3. 2 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/DataAccessDefinition.java
  4. 2 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java
  5. 3 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultDataAccessDefinition.java
  6. 8 32
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/entity/authorization/DataAccessEntity.java
  7. 17 1
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-api/src/main/java/org/hswebframework/web/entity/organizational/PersonEntity.java
  8. 13 2
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/ScopeByUserDataAccessConfig.java
  9. 165 52
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/ScopeByUserHandler.java

+ 20 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/UserAttachEntity.java

@@ -0,0 +1,20 @@
+package org.hswebframework.web.authorization.access;
+
+
+/**
+ * 和user关联的实体
+ *
+ * @author zhouhao
+ * @since 3.0.6
+ */
+public interface UserAttachEntity {
+    String userId = "userId";
+
+    String getUserId();
+
+    void setUserId(String userId);
+
+    default String getUserIdProperty() {
+        return userId;
+    }
+}

+ 5 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresDataAccess.java

@@ -43,7 +43,6 @@ public @interface RequiresDataAccess {
     /**
      * @return permission id ,如果为空将继承 {@link Authorize#permission()}
      * @see Permission#getId()
-     *
      */
     String permission() default "";
 
@@ -82,4 +81,9 @@ public @interface RequiresDataAccess {
      */
     boolean ignore() default false;
 
+    /**
+     * @return 进行控制的实体类类型
+     * @since 3.0.6
+     */
+    Class entityType() default Void.class;
 }

+ 2 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/DataAccessDefinition.java

@@ -4,7 +4,6 @@ package org.hswebframework.web.authorization.define;
 import java.io.Serializable;
 
 /**
- *
  * @author zhouhao
  * @see org.hswebframework.web.authorization.annotation.RequiresDataAccess
  */
@@ -14,6 +13,8 @@ public interface DataAccessDefinition extends Serializable {
 
     String getIdParameterName();
 
+    Class getEntityType();
+
     Phased getPhased();
 
 }

+ 2 - 1
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java

@@ -101,6 +101,7 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition {
         }
         actions.addAll(Arrays.asList(dataAccess.action()));
         DefaultDataAccessDefinition definition = new DefaultDataAccessDefinition();
+        definition.setEntityType(dataAccess.entityType());
         definition.setPhased(dataAccess.phased());
         if (!"".equals(dataAccess.controllerBeanName())) {
             definition.setController(dataAccess.controllerBeanName());
@@ -108,7 +109,7 @@ public class DefaultBasicAuthorizeDefinition implements AopAuthorizeDefinition {
             definition.setController(dataAccess.getClass().getName());
         }
         dataAccessDefinition = definition;
-        dataAccessControl=true;
+        dataAccessControl = true;
     }
 
 

+ 3 - 1
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultDataAccessDefinition.java

@@ -18,7 +18,9 @@ public class DefaultDataAccessDefinition implements DataAccessDefinition {
 
     private String controller;
 
-    private String idParameterName="id";
+    private String idParameterName = "id";
+
+    private Class entityType;
 
     private Phased phased;
 }

+ 8 - 32
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/entity/authorization/DataAccessEntity.java

@@ -1,11 +1,19 @@
 package org.hswebframework.web.entity.authorization;
 
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
 import org.hswebframework.web.commons.entity.CloneableEntity;
 
 /**
  * @author zhouhao
  */
+@Getter
+@Setter
+@EqualsAndHashCode
 public class DataAccessEntity implements CloneableEntity {
+    private static final long serialVersionUID = 2198771924746804915L;
+
     private String action;
 
     private String describe;
@@ -14,38 +22,6 @@ public class DataAccessEntity implements CloneableEntity {
 
     private String config;
 
-    public String getAction() {
-        return this.action;
-    }
-
-    public void setAction(String action) {
-        this.action = action;
-    }
-
-    public String getDescribe() {
-        return this.describe;
-    }
-
-    public void setDescribe(String describe) {
-        this.describe = describe;
-    }
-
-    public String getType() {
-        return this.type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getConfig() {
-        return this.config;
-    }
-
-    public void setConfig(String config) {
-        this.config = config;
-    }
-
     @Override
     public DataAccessEntity clone() {
         DataAccessEntity target = new DataAccessEntity();

+ 17 - 1
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-api/src/main/java/org/hswebframework/web/entity/organizational/PersonEntity.java

@@ -16,15 +16,17 @@
  */
 package org.hswebframework.web.entity.organizational;
 
+import org.hswebframework.web.authorization.access.UserAttachEntity;
 import org.hswebframework.web.commons.entity.GenericEntity;
 import org.hswebframework.web.commons.entity.RecordCreationEntity;
+import org.hswebframework.web.organizational.authorization.access.PersonAttachEntity;
 
 /**
  * 人员 实体
  *
  * @author hsweb-generator-online
  */
-public interface PersonEntity extends GenericEntity<String> {
+public interface PersonEntity extends GenericEntity<String>, PersonAttachEntity, UserAttachEntity {
   /*------------------------------------------
     |               属性名常量               |
     =========================================*/
@@ -141,4 +143,18 @@ public interface PersonEntity extends GenericEntity<String> {
      */
     void setRemark(String remark);
 
+    @Override
+    default String getPersonId() {
+        return getId();
+    }
+
+    @Override
+    default void setPersonId(String personId) {
+        setId(personId);
+    }
+
+    @Override
+    default String getPersonIdProperty() {
+        return "id";
+    }
 }

+ 13 - 2
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/ScopeByUserDataAccessConfig.java

@@ -1,8 +1,8 @@
 package org.hswebframework.web.organizational.authorization.simple;
 
-import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
+import lombok.ToString;
 import org.hswebframework.web.authorization.simple.AbstractDataAccessConfig;
 
 import java.util.Set;
@@ -13,7 +13,7 @@ import java.util.Set;
  */
 @Getter
 @Setter
-@EqualsAndHashCode(callSuper = true)
+@ToString
 public class ScopeByUserDataAccessConfig extends AbstractDataAccessConfig {
 
     private static final long serialVersionUID = 6678003761927318688L;
@@ -30,4 +30,15 @@ public class ScopeByUserDataAccessConfig extends AbstractDataAccessConfig {
     public String getType() {
         return "SCOPE_BY_USER";
     }
+
+    @Override
+    public int hashCode() {
+        return (toString() + getAction()).hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof ScopeByUserDataAccessConfig && obj.hashCode() == hashCode();
+    }
+
 }

+ 165 - 52
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/ScopeByUserHandler.java

@@ -3,25 +3,28 @@ package org.hswebframework.web.organizational.authorization.simple.handler;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.Setter;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.hswebframework.ezorm.core.dsl.Query;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.User;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
+import org.hswebframework.web.authorization.access.UserAttachEntity;
 import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.authorization.define.Phased;
 import org.hswebframework.web.authorization.exception.AccessDenyException;
 import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.bean.FastBeanCopier;
 import org.hswebframework.web.commons.entity.Entity;
+import org.hswebframework.web.commons.entity.PagerResult;
 import org.hswebframework.web.commons.entity.RecordCreationEntity;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.QueryController;
 import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframework.web.organizational.authorization.PersonnelAuthentication;
-import org.hswebframework.web.organizational.authorization.PersonnelAuthenticationHolder;
 import org.hswebframework.web.organizational.authorization.access.*;
 import org.hswebframework.web.organizational.authorization.simple.ScopeByUserDataAccessConfig;
 import org.hswebframework.web.service.QueryService;
@@ -30,6 +33,7 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.util.ClassUtils;
 import org.springframework.util.ReflectionUtils;
 
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
@@ -66,14 +70,19 @@ public class ScopeByUserHandler implements DataAccessHandler {
     }
 
     protected boolean doUpdateAccess(ScopeByUserDataAccessConfig config, AuthorizingContext context) {
-        //获取注解
+        //获取id参数
         Object id = context.getParamContext()
                 .<String>getParameter(context.getDefinition().getDataAccessDefinition().getIdParameterName())
                 .orElse(null);
         if (id == null) {
             return true;
         }
-        PersonnelAuthentication authentication = PersonnelAuthentication.current().orElseThrow(UnAuthorizedException::new);
+        PersonnelAuthentication authentication = PersonnelAuthentication
+                .current().orElse(null);
+        if (authentication == null) {
+            log.warn("当前用户没有关联人员信息!");
+            return false;
+        }
         ScopeInfo scopeInfo = getScope(config, authentication);
         if (scopeInfo.isEmpty()) {
             return false;
@@ -101,10 +110,10 @@ public class ScopeByUserHandler implements DataAccessHandler {
             Object entity = queryService.selectByPk(id);
             if (null != entity) {
                 String targetId = controllerCache.targetIdGetter.apply(entity);
-                log.debug("执行数据权限控制,scope:{},target:{}", scopeInfo.scope, targetId);
                 if (targetId == null) {
                     return true;
                 }
+                log.debug("执行数据权限控制,范围:{},结果:{}", scopeInfo.scope, targetId);
                 return scopeInfo.allScope.contains(controllerCache.targetIdGetter.apply(entity));
             }
         } else {
@@ -114,8 +123,9 @@ public class ScopeByUserHandler implements DataAccessHandler {
 
     }
 
+    @SneakyThrows
     private ScopeInfo getScope(ScopeByUserDataAccessConfig config, PersonnelAuthentication authentication) {
-        String termType = null;
+        String termType = null, personTermType = "in";
         Set<String> scope = null, allScope = null;
         ScopeInfo scopeInfo = new ScopeInfo();
         if (authentication == null) {
@@ -124,43 +134,65 @@ public class ScopeByUserHandler implements DataAccessHandler {
         Consumer<Query<?, QueryParamEntity>> consumer;
 
         switch (config.getScopeType()) {
+            case "OWN_PERSON":
+                termType = "in";
+                scope = Collections.singleton(authentication.getPersonnel().getId());
+                allScope = scope;
+                break;
+            case "OWN_USER":
+                termType = "in";
+                scope = Collections.singleton(Authentication
+                        .current()
+                        .map(Authentication::getUser)
+                        .map(User::getId)
+                        .orElseThrow(AccessDenyException::new));
+                allScope = scope;
+                break;
             case DataAccessType.ORG_SCOPE:
                 termType = "user-in-org";
+                personTermType = "person-in-org";
                 scope = authentication.getRootOrgId();
                 allScope = config.isChildren() ? authentication.getAllOrgId() : scope;
                 break;
             case DataAccessType.DEPARTMENT_SCOPE:
                 termType = "user-in-department";
+                personTermType = "person-in-department";
                 scope = authentication.getRootDepartmentId();
                 allScope = config.isChildren() ? authentication.getAllDepartmentId() : scope;
                 break;
             case DataAccessType.POSITION_SCOPE:
                 termType = "user-in-position";
+                personTermType = "person-in-position";
                 scope = authentication.getRootPositionId();
                 allScope = config.isChildren() ? authentication.getAllPositionId() : scope;
                 break;
             case DataAccessType.DISTRICT_SCOPE:
                 termType = "user-in-dist";
+                personTermType = "person-in-dist";
                 scope = authentication.getRootDistrictId();
                 allScope = config.isChildren() ? authentication.getAllDistrictId() : scope;
                 break;
             case "CUSTOM_SCOPE_ORG":
                 termType = "user-in-org";
+                personTermType = "person-in-org";
                 scope = config.getScope();
                 allScope = scope;
                 break;
             case "CUSTOM_SCOPE_POSITION":
                 termType = "user-in-position";
+                personTermType = "person-in-position";
                 scope = config.getScope();
                 allScope = scope;
                 break;
             case "CUSTOM_SCOPE_DEPT":
                 termType = "user-in-department";
+                personTermType = "person-in-department";
                 scope = config.getScope();
                 allScope = scope;
                 break;
             case "CUSTOM_SCOPE_DIST":
                 termType = "user-in-dist";
+                personTermType = "person-in-dist";
                 scope = config.getScope();
                 allScope = scope;
                 break;
@@ -174,7 +206,12 @@ public class ScopeByUserHandler implements DataAccessHandler {
         scopeInfo.allScope = new ArrayList<>(allScope);
         scopeInfo.termType = termType;
         if (config.isChildren()) {
-            scopeInfo.termType = termType + termType.concat("-child");
+            if (!termType.equals("in")) {
+                scopeInfo.termType = termType.concat("-child");
+            }
+            if (!personTermType.equals("in")) {
+                scopeInfo.personTermType = personTermType.concat("-child");
+            }
         }
         return scopeInfo;
 
@@ -182,6 +219,7 @@ public class ScopeByUserHandler implements DataAccessHandler {
 
     class ScopeInfo {
         String termType;
+        String personTermType;
 
         List<String> scope;
         List<String> allScope;
@@ -194,11 +232,33 @@ public class ScopeByUserHandler implements DataAccessHandler {
     }
 
     static Function<Object, String> defaultTargetIdGetter = entity -> {
-        Map<String, String> userInfo = FastBeanCopier.copy(entity, new HashMap<>(),
-                FastBeanCopier.include("creatorId"));
-        return userInfo.get("creatorId");
+        Map<String, String> userInfo = FastBeanCopier.copy(entity, new HashMap<>(), FastBeanCopier.include("creatorId", "userId"));
+        return userInfo.getOrDefault("userId", userInfo.get("creatorId"));
     };
 
+    protected Function<Object, String> createTargetIdGetter(Class entityClass, String... properties) {
+        String useProperty = null;
+        for (String property : properties) {
+            Field field = ReflectionUtils.findField(entityClass, property);
+            if (field != null) {
+                useProperty = property;
+            }
+        }
+        if (useProperty == null) {
+            log.warn("类[{}]中未包含字段[{}],可能无法进行数据权限控制.", entityClass, Arrays.asList(properties));
+        }
+        return entity -> {
+            Map<String, String> userInfo = FastBeanCopier.copy(entity, new HashMap<>(), FastBeanCopier.include(properties));
+            for (String property : properties) {
+                String value = userInfo.get(property);
+                if (value != null) {
+                    return value;
+                }
+            }
+            return null;
+        };
+    }
+
     static BiConsumer<Query<?, QueryParamEntity>, ScopeInfo> defaultQueryConsumer = (query, scopeInfo) -> {
         query.and("creatorId", scopeInfo.termType, scopeInfo.scope);
     };
@@ -237,59 +297,91 @@ public class ScopeByUserHandler implements DataAccessHandler {
     class CacheKey {
         private String className;
 
+        private String method;
+
         private boolean children;
 
         private String type;
+
+        private boolean queryController;
     }
 
     static Map<CacheKey, ControllerCache> cacheMap = new ConcurrentHashMap<>();
 
 
     private ControllerCache getControllerCache(ScopeByUserDataAccessConfig config, AuthorizingContext context) {
+        Class controller = ClassUtils.getUserClass(context.getParamContext().getTarget().getClass());
         CacheKey cacheKey = new CacheKey();
         cacheKey.children = config.isChildren();
-        cacheKey.className = ClassUtils.getUserClass(context.getParamContext().getTarget().getClass()).getName();
+        cacheKey.className = controller.getName();
+        cacheKey.method = context.getParamContext().getMethod().toString();
         cacheKey.type = config.getScopeType();
+        cacheKey.queryController = context.getParamContext().getTarget() instanceof QueryController;
+        Class dataAccessEntityType = context.getDefinition().getDataAccessDefinition().getEntityType();
+
         return cacheMap.computeIfAbsent(cacheKey, key -> {
             ControllerCache controllerCache = new ControllerCache();
-            if (context.getParamContext().getTarget() instanceof QueryController) {
-                boolean children = config.isChildren();
-                Class controller = ClassUtils.getUserClass(context.getParamContext().getTarget().getClass());
-                Class entityClass = org.hswebframework.utils.ClassUtils.getGenericType(controller, 0);
-                if (OrgAttachEntity.class.isAssignableFrom(entityClass) && config.getScopeType().contains("ORG")) {
-                    controllerCache.targetIdGetter = createGetter(OrgAttachEntity.class, OrgAttachEntity::getOrgId);
-                    controllerCache.queryConsumer = (query, scopeInfo) -> {
-                        query.and(getControlProperty(entityClass, OrgAttachEntity::getOrgIdProperty), children ? "org-child-in" : "in", scopeInfo.scope);
-                    };
-                } else if (DepartmentAttachEntity.class.isAssignableFrom(entityClass) && config.getScopeType().contains("DEPT")) {
-                    controllerCache.targetIdGetter = createGetter(DepartmentAttachEntity.class, DepartmentAttachEntity::getDepartmentId);
-                    controllerCache.queryConsumer = (query, scopeInfo) -> {
-                        query.and(getControlProperty(entityClass, DepartmentAttachEntity::getDepartmentIdProperty), children ? "dept-child-in" : "in", scopeInfo.scope);
-                    };
-                } else if (PositionAttachEntity.class.isAssignableFrom(entityClass) && config.getScopeType().contains("POS")) {
-                    controllerCache.targetIdGetter = createGetter(PositionAttachEntity.class, PositionAttachEntity::getPositionId);
-                    controllerCache.queryConsumer = (query, scopeInfo) -> {
-                        query.and(getControlProperty(entityClass, PositionAttachEntity::getPositionIdProperty), children ? "pos-child-in" : "in", scopeInfo.scope);
-                    };
-                } else if (DistrictAttachEntity.class.isAssignableFrom(entityClass) && config.getScopeType().contains("DIST")) {
-                    controllerCache.targetIdGetter = createGetter(DistrictAttachEntity.class, DistrictAttachEntity::getDistrictId);
+            Class entityClass = dataAccessEntityType;
+            if (entityClass == Void.class) {
+                if (cacheKey.queryController) {
+                    entityClass = org.hswebframework.utils.ClassUtils.getGenericType(controller, 0);
+                }
+            }
+            boolean children = cacheKey.isChildren();
+            //控制机构
+            if (cacheKey.getType().contains("ORG") && OrgAttachEntity.class.isAssignableFrom(entityClass)) {
+                String property = getControlProperty(entityClass, OrgAttachEntity::getOrgIdProperty);
+                controllerCache.targetIdGetter = createGetter(OrgAttachEntity.class, OrgAttachEntity::getOrgId);
+                controllerCache.queryConsumer = (query, scopeInfo) -> {
+                    query.and(property, children ? "org-child-in" : "in", scopeInfo.scope);
+                };
+                //部门
+            } else if (cacheKey.getType().contains("DEPT") && DepartmentAttachEntity.class.isAssignableFrom(entityClass)) {
+                String property = getControlProperty(entityClass, DepartmentAttachEntity::getDepartmentIdProperty);
+                controllerCache.targetIdGetter = createGetter(DepartmentAttachEntity.class, DepartmentAttachEntity::getDepartmentId);
+                controllerCache.queryConsumer = (query, scopeInfo) -> {
+                    query.and(property, children ? "org-child-in" : "in", scopeInfo.scope);
+                };
+                //岗位
+            } else if (cacheKey.getType().contains("POS") && PositionAttachEntity.class.isAssignableFrom(entityClass)) {
+                String property = getControlProperty(entityClass, PositionAttachEntity::getPositionIdProperty);
+                controllerCache.targetIdGetter = createGetter(PositionAttachEntity.class, PositionAttachEntity::getPositionId);
+                controllerCache.queryConsumer = (query, scopeInfo) -> {
+                    query.and(property, children ? "pos-child-in" : "in", scopeInfo.scope);
+                };
+                //行政区划
+            } else if (cacheKey.getType().contains("DIST") && DistrictAttachEntity.class.isAssignableFrom(entityClass)) {
+                String property = getControlProperty(entityClass, DistrictAttachEntity::getDistrictIdProperty);
+                controllerCache.targetIdGetter = createGetter(DistrictAttachEntity.class, DistrictAttachEntity::getDistrictId);
+                controllerCache.queryConsumer = (query, scopeInfo) -> {
+                    query.and(property, children ? "dist-child-in" : "in", scopeInfo.scope);
+                };
+                //人员
+            } else if (cacheKey.getType().contains("PERSON") && PersonAttachEntity.class.isAssignableFrom(entityClass)) {
+                String property = getControlProperty(entityClass, PersonAttachEntity::getPersonIdProperty);
+                controllerCache.targetIdGetter = createGetter(PersonAttachEntity.class, PersonAttachEntity::getPersonId);
+                controllerCache.queryConsumer = (query, scopeInfo) -> {
+                    query.and(property, scopeInfo.termType, scopeInfo.scope);
+                };
+                //根据用户控制
+            } else {
+                if (UserAttachEntity.class.isAssignableFrom(entityClass)) {
+                    String property = getControlProperty(entityClass, UserAttachEntity::getUserIdProperty);
+                    controllerCache.targetIdGetter = createGetter(UserAttachEntity.class, UserAttachEntity::getUserId);
                     controllerCache.queryConsumer = (query, scopeInfo) -> {
-                        query.and(getControlProperty(entityClass, DistrictAttachEntity::getDistrictIdProperty), children ? "dist-child-in" : "in", scopeInfo.scope);
+                        query.and(property, scopeInfo.termType, scopeInfo.scope);
                     };
                 } else if (RecordCreationEntity.class.isAssignableFrom(entityClass)) {
+                    String property = getControlProperty(entityClass, RecordCreationEntity::getCreatorIdProperty);
                     controllerCache.targetIdGetter = createGetter(RecordCreationEntity.class, RecordCreationEntity::getCreatorId);
                     controllerCache.queryConsumer = (query, scopeInfo) -> {
-                        query.and(getControlProperty(entityClass, RecordCreationEntity::getCreatorIdProperty), scopeInfo.termType, scopeInfo.scope);
+                        query.and(property, scopeInfo.termType, scopeInfo.scope);
                     };
                 } else {
-                    String userIdField = getUserField(entityClass);
-                    controllerCache.targetIdGetter = entity -> {
-                        Map<String, String> userInfo = FastBeanCopier.copy(entity, new HashMap<>(),
-                                FastBeanCopier.include(userIdField));
-                        return userInfo.get(userIdField);
-                    };
+                    String property = getUserField(entityClass);
+                    controllerCache.targetIdGetter = createTargetIdGetter(entityClass, property);
                     controllerCache.queryConsumer = (query, scopeInfo) -> {
-                        query.and(userIdField, scopeInfo.termType, scopeInfo.scope);
+                        query.and(property, scopeInfo.termType, scopeInfo.scope);
                     };
                 }
             }
@@ -313,18 +405,24 @@ public class ScopeByUserHandler implements DataAccessHandler {
             if (result == null) {
                 return true;
             }
-            if (result instanceof ResponseEntity) {
-                result = ((ResponseEntity) result).getBody();
-            }
-            if (result instanceof ResponseMessage) {
-                result = ((ResponseMessage) result).getResult();
-            }
-            String value = controllerCache.targetIdGetter.apply(result);
-            log.debug("执行数据权限控制[{}],scope:{},target:{}", config.getScopeTypeName(), scopeInfo.scope, value);
-            if (value == null) {
-                return true;
+            result = getRealResult(result);
+            Predicate<Object> predicate = (o) -> {
+                String value = controllerCache.targetIdGetter.apply(o);
+                if (value == null) {
+                    return true;
+                }
+                log.debug("执行数据权限控制[{}],scope:{},target:{}", config.getScopeTypeName(), scopeInfo.scope, value);
+                return scopeInfo.allScope.contains(value);
+            };
+            if (result instanceof Collection) {
+                Collection<?> res = ((Collection) result);
+                if (res.isEmpty()) {
+                    return true;
+                }
+                return res.stream().allMatch(predicate);
+            } else {
+                return predicate.test(result);
             }
-            return scopeInfo.allScope.contains(value);
         }
 
         Entity entity = context.getParamContext()
@@ -339,9 +437,11 @@ public class ScopeByUserHandler implements DataAccessHandler {
         if (entity instanceof QueryParamEntity) {
             QueryParamEntity param = ((QueryParamEntity) entity);
             param.toNestQuery(query -> {
-                log.debug("执行查询数据权限控制[{}],scope:{}", config.getScopeTypeName(), scopeInfo.scope);
+                log.debug("执行查询数据权限控制[{}],范围:{}", config.getScopeTypeName(), scopeInfo.scope);
                 controllerCache.queryConsumer.accept(query, scopeInfo);
             });
+        } else {
+            log.warn("方法[{}]未使用动态查询参数[QueryParamEntity],无法进行数据权限控制!", context.getParamContext().getMethod());
         }
         return true;
     }
@@ -354,4 +454,17 @@ public class ScopeByUserHandler implements DataAccessHandler {
 
         return "creatorId";
     }
+
+    protected Object getRealResult(Object result) {
+        if (result instanceof ResponseEntity) {
+            result = ((ResponseEntity) result).getBody();
+        }
+        if (result instanceof ResponseMessage) {
+            result = ((ResponseMessage) result).getResult();
+        }
+        if (result instanceof PagerResult) {
+            result = ((PagerResult) result).getData();
+        }
+        return result;
+    }
 }