Ver Fonte

优化权限控制,增加测试用例

zhou-hao há 7 anos atrás
pai
commit
133fd1ab28
13 ficheiros alterados com 442 adições e 149 exclusões
  1. 6 0
      hsweb-authorization/hsweb-authorization-basic/pom.xml
  2. 24 4
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java
  3. 12 79
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java
  4. 6 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/EmptyAuthorizeDefinition.java
  5. 0 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java
  6. 5 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/MethodProceedCallback.java
  7. 5 6
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java
  8. 40 11
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java
  9. 52 19
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldScopeDataAccessHandler.java
  10. 16 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/InvokeResultUtils.java
  11. 61 27
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/OwnCreatedDataAccessHandler.java
  12. 0 2
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/ScriptDataAccessHandler.java
  13. 215 0
      hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/AuthorizeDefinitionTests.java

+ 6 - 0
hsweb-authorization/hsweb-authorization-basic/pom.xml

@@ -65,6 +65,12 @@
             <artifactId>redisson</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-all</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 24 - 4
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java

@@ -7,20 +7,26 @@ import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.authorization.basic.handler.AuthorizingHandler;
 import org.hswebframework.web.authorization.define.AuthorizeDefinition;
+import org.hswebframework.web.authorization.define.Phased;
 import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
+import org.hswebframework.web.controller.message.ResponseMessage;
 import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.lang.reflect.Method;
+import java.util.Map;
 
 /**
  * @author zhouhao
  */
 public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor {
 
+    private static final long serialVersionUID = 1154190623020670672L;
+
     public AopAuthorizingController(AuthorizingHandler authorizingHandler, AopMethodAuthorizeDefinitionParser aopMethodAuthorizeDefinitionParser) {
         super((MethodInterceptor) methodInvocation -> {
 
@@ -29,22 +35,36 @@ public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor
             MethodInterceptorContext paramContext = holder.createParamContext();
 
             AuthorizeDefinition definition = aopMethodAuthorizeDefinitionParser.parse(paramContext);
-
+            Object result = true;
+            boolean isControl = false;
             if (null != definition) {
                 Authentication authentication = Authentication.current().orElseThrow(UnAuthorizedException::new);
-
                 if (!definition.isEmpty()) {
                     AuthorizingContext context = new AuthorizingContext();
                     context.setAuthentication(authentication);
                     context.setDefinition(definition);
                     context.setParamContext(paramContext);
-                    authorizingHandler.handle(context);
+                    isControl = true;
+                    if (definition.getPhased() == Phased.before) {
+                        authorizingHandler.handle(context);
+                        result = methodInvocation.proceed();
+                    } else {
+                        result = methodInvocation.proceed();
+                        context.setParamContext(holder.createParamContext(result));
+                        authorizingHandler.handle(context);
+                    }
                 }
             }
-            return methodInvocation.proceed();
+            if (!isControl) {
+                result = methodInvocation.proceed();
+            }
+
+            return result;
         });
     }
 
+
+
     @Override
     public boolean matches(Method method, Class<?> aClass) {
         //对controller进行控制

+ 12 - 79
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java

@@ -1,5 +1,6 @@
 package org.hswebframework.web.authorization.basic.define;
 
+import lombok.*;
 import org.hswebframework.web.authorization.access.DataAccessController;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.annotation.Logical;
@@ -7,6 +8,7 @@ import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
 import org.hswebframework.web.authorization.annotation.RequiresExpression;
 import org.hswebframework.web.authorization.define.AuthorizeDefinition;
 import org.hswebframework.web.authorization.define.DataAccessDefinition;
+import org.hswebframework.web.authorization.define.Phased;
 import org.hswebframework.web.authorization.define.Script;
 
 import java.util.Arrays;
@@ -19,6 +21,10 @@ import java.util.Set;
  * @author zhouhao
  * @since 3.0
  */
+@Getter
+@Setter
+@NoArgsConstructor
+@AllArgsConstructor
 public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
     private boolean dataAccessControl;
 
@@ -38,49 +44,16 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
 
     private DataAccessDefinition dataAccessDefinition;
 
-    @Override
-    public int getPriority() {
-        return Integer.MIN_VALUE;
-    }
-
-    @Override
-    public boolean isDataAccessControl() {
-        return dataAccessControl;
-    }
-
-    @Override
-    public Set<String> getPermissions() {
-        return new HashSet<>(permissions);
-    }
+    private Phased phased = Phased.before;
 
     @Override
-    public Set<String> getActions() {
-        return new HashSet<>(actions);
+    public Phased getPhased() {
+        return phased;
     }
 
     @Override
-    public Set<String> getRoles() {
-        return new HashSet<>(roles);
-    }
-
-    @Override
-    public Set<String> getUser() {
-        return new HashSet<>(user);
-    }
-
-    @Override
-    public Script getScript() {
-        return script;
-    }
-
-    @Override
-    public String getMessage() {
-        return message;
-    }
-
-    @Override
-    public Logical getLogical() {
-        return logical;
+    public int getPriority() {
+        return Integer.MIN_VALUE;
     }
 
     @Override
@@ -88,47 +61,6 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
         return permissions.isEmpty() && roles.isEmpty() && user.isEmpty() && script == null && dataAccessDefinition == null;
     }
 
-    @Override
-    public DataAccessDefinition getDataAccessDefinition() {
-        return dataAccessDefinition;
-    }
-
-    public void setDataAccessDefinition(DataAccessDefinition dataAccessDefinition) {
-        this.dataAccessDefinition = dataAccessDefinition;
-    }
-
-    public void setActions(Set<String> actions) {
-        this.actions = actions;
-    }
-
-    public void setDataAccessControl(boolean dataAccessControl) {
-        this.dataAccessControl = dataAccessControl;
-    }
-
-    public void setLogical(Logical logical) {
-        this.logical = logical;
-    }
-
-    public void setMessage(String message) {
-        this.message = message;
-    }
-
-    public void setPermissions(Set<String> permissions) {
-        this.permissions = permissions;
-    }
-
-    public void setRoles(Set<String> roles) {
-        this.roles = roles;
-    }
-
-    public void setScript(Script script) {
-        this.script = script;
-    }
-
-    public void setUser(Set<String> user) {
-        this.user = user;
-    }
-
     public void put(Authorize authorize) {
         if (null == authorize || authorize.ignore()) {
             return;
@@ -141,6 +73,7 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
             logical = authorize.logical();
         }
         message = authorize.message();
+        phased=authorize.phased();
     }
 
     public void put(RequiresExpression expression) {

+ 6 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/EmptyAuthorizeDefinition.java

@@ -3,6 +3,7 @@ package org.hswebframework.web.authorization.basic.define;
 import org.hswebframework.web.authorization.annotation.Logical;
 import org.hswebframework.web.authorization.define.AuthorizeDefinition;
 import org.hswebframework.web.authorization.define.DataAccessDefinition;
+import org.hswebframework.web.authorization.define.Phased;
 import org.hswebframework.web.authorization.define.Script;
 
 import java.util.Set;
@@ -17,6 +18,11 @@ public class EmptyAuthorizeDefinition implements AuthorizeDefinition {
     private EmptyAuthorizeDefinition() {
     }
 
+    @Override
+    public Phased getPhased() {
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public int getPriority() {
         throw new UnsupportedOperationException();

+ 0 - 1
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java

@@ -52,7 +52,6 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
 
         //表达式权限控制
         handleExpression(context.getAuthentication(), context.getDefinition(), context.getParamContext());
-
     }
 
     protected void handleDataAccess(AuthorizingContext context) {

+ 5 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/MethodProceedCallback.java

@@ -0,0 +1,5 @@
+package org.hswebframework.web.authorization.basic.handler;
+
+public interface MethodProceedCallback {
+    void  call(Object result);
+}

+ 5 - 6
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java

@@ -30,11 +30,11 @@ public final class DefaultDataAccessController implements DataAccessController {
             throw new UnsupportedOperationException();
         }
         this.parent = parent;
-        addHandler(new CustomDataAccessHandler());
-        addHandler(new OwnCreatedDataAccessHandler());
-        addHandler(new ScriptDataAccessHandler());
-        addHandler(new FieldFilterDataAccessHandler());
-        addHandler(new FieldScopeDataAccessHandler());
+        addHandler(new CustomDataAccessHandler()).
+                addHandler(new OwnCreatedDataAccessHandler()).
+                addHandler(new ScriptDataAccessHandler()).
+                addHandler(new FieldFilterDataAccessHandler()).
+                addHandler(new FieldScopeDataAccessHandler());
     }
 
     @Override
@@ -43,7 +43,6 @@ public final class DefaultDataAccessController implements DataAccessController {
             parent.doAccess(access, context);
         }
         return handlers.stream()
-                // TODO: 17-3-28 可以换成access对应的handler以提高效率
                 .filter(handler -> handler.isSupport(access))
                 .allMatch(handler -> handler.handle(access, context));
     }

+ 40 - 11
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java

@@ -6,13 +6,19 @@ import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
 import org.hswebframework.web.authorization.access.FieldFilterDataAccessConfig;
 import org.hswebframework.web.authorization.define.AuthorizingContext;
+import org.hswebframework.web.authorization.define.Phased;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.commons.model.Model;
+import org.hswebframework.web.controller.message.ResponseMessage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
 
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * 数据权限字段过滤处理,目前仅支持deny. {@link DataAccessConfig.DefaultType#DENY_FIELDS}
@@ -33,6 +39,7 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
 
         switch (access.getAction()) {
             case Permission.ACTION_QUERY:
+            case Permission.ACTION_GET:
                 return doQueryAccess(filterDataAccessConfig, context);
             case Permission.ACTION_UPDATE:
                 return doUpdateAccess(filterDataAccessConfig, context);
@@ -53,7 +60,7 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
      */
     protected boolean doUpdateAccess(FieldFilterDataAccessConfig accesses, AuthorizingContext params) {
         Object supportParam = params.getParamContext().getParams().values().stream()
-                .filter(param -> (param instanceof Entity) || (param instanceof Model)||(param instanceof Map))
+                .filter(param -> (param instanceof Entity) || (param instanceof Model) || (param instanceof Map))
                 .findAny()
                 .orElse(null);
         if (null != supportParam) {
@@ -73,18 +80,40 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
         return true;
     }
 
-
+    @SuppressWarnings("all")
     protected boolean doQueryAccess(FieldFilterDataAccessConfig access, AuthorizingContext context) {
-        QueryParamEntity entity = context.getParamContext().getParams()
-                .values().stream()
-                .filter(QueryParamEntity.class::isInstance)
-                .map(QueryParamEntity.class::cast)
-                .findAny().orElse(null);
-        if (entity == null) {
-            logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity");
-            return true;
+        if (context.getDefinition().getPhased() == Phased.before) {
+            QueryParamEntity entity = context.getParamContext().getParams()
+                    .values().stream()
+                    .filter(QueryParamEntity.class::isInstance)
+                    .map(QueryParamEntity.class::cast)
+                    .findAny().orElse(null);
+            if (entity == null) {
+                logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity");
+                return true;
+            }
+            entity.excludes(access.getFields().toArray(new String[access.getFields().size()]));
+        } else {
+            Object result = InvokeResultUtils.convertRealResult(context.getParamContext().getInvokeResult());
+            if (result instanceof Collection) {
+                ((Collection) result).forEach(o -> setObjectPropertyNull(o, access.getFields()));
+            } else {
+                setObjectPropertyNull(result, access.getFields());
+            }
         }
-        entity.excludes(access.getFields().toArray(new String[access.getFields().size()]));
         return true;
     }
+
+    protected void setObjectPropertyNull(Object obj, Set<String> fields) {
+        if (null == obj) {
+            return;
+        }
+        for (String field : fields) {
+            try {
+                BeanUtilsBean.getInstance().getPropertyUtils().setProperty(obj, field, null);
+            } catch (Exception ignore) {
+
+            }
+        }
+    }
 }

+ 52 - 19
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldScopeDataAccessHandler.java

@@ -9,14 +9,18 @@ import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
 import org.hswebframework.web.authorization.access.FieldScopeDataAccessConfig;
 import org.hswebframework.web.authorization.define.AuthorizingContext;
+import org.hswebframework.web.authorization.define.Phased;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.QueryController;
 import org.hswebframework.web.service.QueryService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 /**
  * @author zhouhao
@@ -38,8 +42,8 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
         if (controller != null) {
             switch (access.getAction()) {
                 case Permission.ACTION_QUERY:
-                    return doQueryAccess(own, context);
                 case Permission.ACTION_GET:
+                    return doQueryAccess(own, context);
                 case Permission.ACTION_DELETE:
                 case Permission.ACTION_UPDATE:
                     return doRWAccess(own, context, controller);
@@ -78,29 +82,58 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
     }
 
 
+    @SuppressWarnings("all")
     protected boolean doQueryAccess(FieldScopeDataAccessConfig access, AuthorizingContext context) {
-        QueryParamEntity entity = context.getParamContext().getParams()
-                .values().stream()
-                .filter(QueryParamEntity.class::isInstance)
-                .map(QueryParamEntity.class::cast)
-                .findAny().orElse(null);
-        if (entity == null) {
-            logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity");
-            return true;
+        if (context.getDefinition().getPhased() == Phased.before) {
+            QueryParamEntity entity = context.getParamContext().getParams()
+                    .values().stream()
+                    .filter(QueryParamEntity.class::isInstance)
+                    .map(QueryParamEntity.class::cast)
+                    .findAny().orElse(null);
+            if (entity == null) {
+                logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity");
+                return true;
+            }
+            //重构查询条件
+            //如: 旧的条件为 where column =? or column = ?
+            //重构后为: where creatorId=? and (column = ? or column = ?)
+            List<Term> oldParam = entity.getTerms();
+            //清空旧的查询条件
+            entity.setTerms(new ArrayList<>());
+            //添加一个查询条件
+            entity.addTerm(createQueryTerm(access))
+                    //客户端提交的参数 作为嵌套参数
+                    .nest().setTerms(oldParam);
+        } else {
+            Object result = InvokeResultUtils.convertRealResult(context.getParamContext().getInvokeResult());
+            if (result == null) {
+                return true;
+            }
+            if (result instanceof Collection) {
+                return ((Collection) result).stream().allMatch(obj -> propertyInScope(obj, access.getField(), access.getScope()));
+            } else {
+                return propertyInScope(result, access.getField(), access.getScope());
+            }
         }
-        //重构查询条件
-        //如: 旧的条件为 where column =? or column = ?
-        //重构后为: where creatorId=? and (column = ? or column = ?)
-        List<Term> oldParam = entity.getTerms();
-        //清空旧的查询条件
-        entity.setTerms(new ArrayList<>());
-        //添加一个查询条件
-        entity.addTerm(createQueryTerm(access))
-                //客户端提交的参数 作为嵌套参数
-                .nest().setTerms(oldParam);
         return true;
     }
 
+    protected boolean propertyInScope(Object obj, String property, Set<Object> scope) {
+        if (null == obj) {
+            return false;
+        }
+        try {
+            Object value = BeanUtilsBean.getInstance().getProperty(obj, property);
+            if (null != value) {
+                return scope.contains(value);
+            }
+        } catch (Exception ignore) {
+            logger.warn("can not get property {} from {},{}", property, obj, ignore.getMessage());
+        }
+        return true;
+
+    }
+
     protected Term createQueryTerm(FieldScopeDataAccessConfig access) {
         Term term = new Term();
         term.setType(Term.Type.and);

+ 16 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/InvokeResultUtils.java

@@ -0,0 +1,16 @@
+package org.hswebframework.web.authorization.basic.handler.access;
+
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.springframework.http.ResponseEntity;
+
+public class InvokeResultUtils {
+    public static Object convertRealResult(Object result) {
+        if (result instanceof ResponseMessage) {
+            return ((ResponseMessage) result).getResult();
+        }
+        if (result instanceof ResponseEntity) {
+            return ((ResponseEntity) result).getBody();
+        }
+        return result;
+    }
+}

+ 61 - 27
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/OwnCreatedDataAccessHandler.java

@@ -1,5 +1,7 @@
 package org.hswebframework.web.authorization.basic.handler.access;
 
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.commons.beanutils.PropertyUtilsBean;
 import org.hswebframework.ezorm.core.param.Term;
 import org.hswebframework.utils.ClassUtils;
 import org.hswebframework.web.authorization.Permission;
@@ -7,6 +9,7 @@ import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
 import org.hswebframework.web.authorization.access.OwnCreatedDataAccessConfig;
 import org.hswebframework.web.authorization.define.AuthorizingContext;
+import org.hswebframework.web.authorization.define.Phased;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.RecordCreationEntity;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
@@ -15,12 +18,14 @@ import org.hswebframework.web.service.QueryService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
 public class OwnCreatedDataAccessHandler implements DataAccessHandler {
@@ -37,12 +42,13 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
         Object controller = context.getParamContext().getTarget();
         if (controller != null) {
             switch (access.getAction()) {
+                case Permission.ACTION_GET:
                 case Permission.ACTION_QUERY:
                     return doQueryAccess(own, context);
-                case Permission.ACTION_GET:
+
                 case Permission.ACTION_DELETE:
                 case Permission.ACTION_UPDATE:
-                    return doRWAccess(own, context,controller);
+                    return doRWAccess(own, context, controller);
                 case Permission.ACTION_ADD:
                     //put creator_id to result
                     return putCreatorId(own, context);
@@ -91,32 +97,60 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
     }
 
     protected boolean doQueryAccess(OwnCreatedDataAccessConfig access, AuthorizingContext context) {
-        Entity entity = context.getParamContext().getParams()
-                .values().stream()
-                .filter(Entity.class::isInstance)
-                .map(Entity.class::cast)
-                .findAny().orElse(null);
-        if (entity == null) {
-            logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity");
+        String userId = context.getAuthentication().getUser().getId();
+
+        if (context.getDefinition().getPhased() == Phased.before) {
+            Entity entity = context.getParamContext().getParams()
+                    .values().stream()
+                    .filter(Entity.class::isInstance)
+                    .map(Entity.class::cast)
+                    .findAny().orElse(null);
+            if (entity == null) {
+                logger.warn("try validate query access, but query entity is null or not instance of org.hswebframework.web.commons.entity.Entity");
+                return true;
+            }
+            if (entity instanceof QueryParamEntity) {
+                QueryParamEntity queryParamEntity = ((QueryParamEntity) entity);
+                //重构查询条件
+                //如: 旧的条件为 where name =? or name = ?
+                //重构后为: where creatorId=? and (name = ? or name = ?)
+                List<Term> oldParam = queryParamEntity.getTerms();
+                //清空旧的查询条件
+                queryParamEntity.setTerms(new ArrayList<>());
+                //添加一个查询条件
+                queryParamEntity
+                        .where(RecordCreationEntity.creatorId, userId)
+                        //客户端提交的参数 作为嵌套参数
+                        .nest().setTerms(oldParam);
+            } else if (entity instanceof RecordCreationEntity) {
+                ((RecordCreationEntity) entity).setCreatorId(userId);
+            } else {
+                logger.warn("try validate query access,but entity not support, QueryParamEntity and RecordCreationEntity support now!");
+            }
+        } else {
+            Object result = InvokeResultUtils.convertRealResult(context.getParamContext().getInvokeResult());
+            return matchCreatorId(result, userId);
+        }
+        return true;
+    }
+
+    @SuppressWarnings("all")
+    protected boolean matchCreatorId(Object result, String userId) {
+        if (null == result) {
             return true;
         }
-        if (entity instanceof QueryParamEntity) {
-            QueryParamEntity queryParamEntity = ((QueryParamEntity) entity);
-            //重构查询条件
-            //如: 旧的条件为 where name =? or name = ?
-            //重构后为: where creatorId=? and (name = ? or name = ?)
-            List<Term> oldParam = queryParamEntity.getTerms();
-            //清空旧的查询条件
-            queryParamEntity.setTerms(new ArrayList<>());
-            //添加一个查询条件
-            queryParamEntity
-                    .where(RecordCreationEntity.creatorId,context.getAuthentication().getUser().getId())
-                    //客户端提交的参数 作为嵌套参数
-                    .nest().setTerms(oldParam);
-        } else if (entity instanceof RecordCreationEntity) {
-            ((RecordCreationEntity) entity).setCreatorId(context.getAuthentication().getUser().getId());
+        if (result instanceof RecordCreationEntity) {
+            return userId.equals(((RecordCreationEntity) result).getCreatorId());
+        } else if (result instanceof Collection) {
+            Collection<?> collection = ((Collection) result);
+            //删掉不能访问的对象
+            collection.removeAll(collection.stream().filter((Object o) -> !matchCreatorId(o, userId))
+                    .collect(Collectors.toList()));
         } else {
-            logger.warn("try validate query access,but entity not support, QueryParamEntity and RecordCreationEntity support now!");
+            try {
+                return userId.equals(PropertyUtils.getProperty(result, "creatorId"));
+            } catch (Exception ignore) {
+            }
         }
         return true;
     }

+ 0 - 2
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/ScriptDataAccessHandler.java

@@ -11,8 +11,6 @@ import org.hswebframework.web.authorization.access.ScriptDataAccessConfig;
 import org.hswebframework.web.authorization.define.AuthorizingContext;
 
 /**
- * TODO 完成注释
- *
  * @author zhouhao
  */
 public class ScriptDataAccessHandler implements DataAccessHandler {

+ 215 - 0
hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/AuthorizeDefinitionTests.java

@@ -0,0 +1,215 @@
+package org.hswebframework.web.authorization;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import lombok.*;
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
+import org.hswebframework.web.authorization.basic.aop.AopMethodAuthorizeDefinitionParser;
+import org.hswebframework.web.authorization.basic.aop.DefaultAopMethodAuthorizeDefinitionParser;
+import org.hswebframework.web.authorization.basic.handler.DefaultAuthorizingHandler;
+import org.hswebframework.web.authorization.basic.handler.access.DefaultDataAccessController;
+import org.hswebframework.web.authorization.define.AuthorizeDefinition;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
+import org.hswebframework.web.authorization.define.Phased;
+import org.hswebframework.web.authorization.simple.*;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.controller.message.ResponseMessage;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.*;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuthorizeDefinitionTests {
+
+    @Mock
+    private MethodInterceptorContext queryById;
+    @Mock
+    private MethodInterceptorContext dynamicQuery;
+
+    @Mock
+    private Authentication authentication;
+
+    AopMethodAuthorizeDefinitionParser parser = new DefaultAopMethodAuthorizeDefinitionParser();
+
+
+    @Before
+    public void init() throws NoSuchMethodException {
+        TestClass testClass = new TestClass();
+
+        QueryParamEntity entity = new QueryParamEntity();
+        entity.where("id", "admin").or("name", "admin");
+
+        User user = User.builder().name("test").id("test")
+                .orgId("400000")
+                .password("admin").salt("1234").build();
+
+        //mock MethodInterceptorContext
+        when(queryById.getMethod()).thenReturn(TestClass.class.getMethod("queryById", String.class));
+        when(queryById.getTarget()).thenReturn(testClass);
+        when(queryById.getParameter("id")).thenReturn(Optional.of("test"));
+        when(queryById.getParams()).thenReturn(Collections.singletonMap("id", "test"));
+        when(queryById.getInvokeResult()).thenReturn(ResponseMessage.ok(user));
+
+
+        //mock MethodInterceptorContext
+        when(dynamicQuery.getMethod()).thenReturn(TestClass.class.getMethod("dynamicQuery", QueryParamEntity.class));
+        when(dynamicQuery.getTarget()).thenReturn(testClass);
+        when(dynamicQuery.getParams()).thenReturn(Collections.singletonMap("paramEntity", entity));
+        when(dynamicQuery.getParameter("paramEntity")).thenReturn(Optional.of(entity));
+
+
+        //过滤字段
+        AbstractDataAccessConfig fieldFilter = new SimpleFieldFilterDataAccessConfig("password", "salt");
+        fieldFilter.setAction(Permission.ACTION_QUERY);
+
+        SimpleFiledScopeDataAccessConfig filedScope = new SimpleFiledScopeDataAccessConfig();
+        filedScope.setAction(Permission.ACTION_QUERY);
+        filedScope.setField("orgId");
+        filedScope.setScopeType("org");
+        filedScope.setScope(Collections.singleton("400000"));
+
+        //mock authentication
+        when(authentication.getUser()).thenReturn(SimpleUser.builder().id("admin").name("admin").build());
+        when(authentication.getPermissions()).thenReturn(Arrays.asList(SimplePermission.builder()
+                .id("test")
+                .dataAccesses(new HashSet<>(Arrays.asList(fieldFilter, filedScope)))
+
+                .actions(new HashSet<>(Arrays.asList(Permission.ACTION_QUERY, Permission.ACTION_UPDATE))).build()));
+
+    }
+
+
+    @Test
+    public void testParseAuthorizeDefinition() {
+        AuthorizeDefinition definition = parser.parse(queryById);
+
+        Assert.assertNotNull(definition);
+        Assert.assertEquals(definition.getPermissions().size(), 1);
+        Assert.assertEquals(definition.getPermissions().iterator().next(), "test");
+        Assert.assertEquals(definition.getActions().iterator().next(), Permission.ACTION_QUERY);
+    }
+
+    @Test
+    public void testAuthorizingHandler() {
+        DefaultAuthorizingHandler handler = new DefaultAuthorizingHandler();
+
+        AuthorizeDefinition definition = parser.parse(queryById);
+
+        AuthorizingContext authorizingContext = new AuthorizingContext();
+        authorizingContext.setAuthentication(authentication);
+        authorizingContext.setDefinition(definition);
+        authorizingContext.setParamContext(queryById);
+
+        handler.handle(authorizingContext);
+
+
+    }
+
+    /**
+     * 测试数据权限控制s
+     */
+    @Test
+    public void testDynamicQueryDataAccessHandler() {
+
+        DefaultAuthorizingHandler handler = new DefaultAuthorizingHandler();
+        DefaultDataAccessController controller = new DefaultDataAccessController();
+        handler.setDataAccessController(controller);
+
+
+        AuthorizeDefinition definition = parser.parse(dynamicQuery);
+
+        //获取到请求参数
+        QueryParamEntity entity = dynamicQuery.<QueryParamEntity>getParameter("paramEntity").orElseThrow(NullPointerException::new);
+        System.out.println(JSON.toJSONString(entity, SerializerFeature.PrettyFormat));
+
+        AuthorizingContext authorizingContext = new AuthorizingContext();
+        authorizingContext.setAuthentication(authentication);
+        authorizingContext.setDefinition(definition);
+        authorizingContext.setParamContext(dynamicQuery);
+
+        handler.handle(authorizingContext);
+
+        System.out.println(JSON.toJSONString(entity, SerializerFeature.PrettyFormat));
+
+        Assert.assertTrue(entity.getExcludes().size() == 2);
+        Assert.assertTrue(entity.getTerms().size() == 2);
+        Assert.assertTrue(entity.getTerms().get(1).getTerms().size() == 2);
+    }
+
+    /**
+     * 测试数据权限控制s
+     */
+    @Test
+    public void testGetDataAccessHandler() {
+
+        DefaultAuthorizingHandler handler = new DefaultAuthorizingHandler();
+        DefaultDataAccessController controller = new DefaultDataAccessController();
+        handler.setDataAccessController(controller);
+
+
+        AuthorizeDefinition definition = parser.parse(queryById);
+
+        //响应结果
+        Object response = queryById.getInvokeResult();
+
+        System.out.println(JSON.toJSONString(response, SerializerFeature.PrettyFormat));
+
+        AuthorizingContext authorizingContext = new AuthorizingContext();
+        authorizingContext.setAuthentication(authentication);
+        authorizingContext.setDefinition(definition);
+        authorizingContext.setParamContext(queryById);
+
+         handler.handle(authorizingContext);
+
+        System.out.println(JSON.toJSONString(response, SerializerFeature.PrettyFormat));
+        Assert.assertTrue(response instanceof ResponseMessage);
+        Assert.assertTrue(((User) ((ResponseMessage) response).getResult()).getPassword() == null);
+        Assert.assertTrue(((User) ((ResponseMessage) response).getResult()).getSalt() == null);
+    }
+
+    @Authorize(permission = "test")
+    public static class TestClass {
+
+        @Authorize(action = Permission.ACTION_QUERY, phased = Phased.after, dataAccess = @RequiresDataAccess)
+        public ResponseMessage<User> queryById(String id) {
+            return ResponseMessage.ok();
+        }
+
+        @Authorize(action = Permission.ACTION_QUERY)
+        @RequiresDataAccess
+        public void dynamicQuery(QueryParamEntity paramEntity) {
+            System.out.println(JSON.toJSON(paramEntity));
+        }
+
+    }
+
+    @Getter
+    @Setter
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class User {
+        private String id;
+
+        private String name;
+
+        private String password;
+
+        private String salt;
+
+        private String orgId;
+
+    }
+}