diff --git a/hsweb-authorization/hsweb-authorization-basic/pom.xml b/hsweb-authorization/hsweb-authorization-basic/pom.xml
index e6f8108e9..e66f5c657 100644
--- a/hsweb-authorization/hsweb-authorization-basic/pom.xml
+++ b/hsweb-authorization/hsweb-authorization-basic/pom.xml
@@ -65,6 +65,12 @@
redisson
test
+
+ org.mockito
+ mockito-all
+ 1.10.19
+ test
+
\ No newline at end of file
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java
index bed5917c1..4a16889d7 100644
--- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java
+++ b/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进行控制
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java
index ed29ae94e..733c846e9 100644
--- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java
+++ b/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,97 +44,23 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
private DataAccessDefinition dataAccessDefinition;
+ private Phased phased = Phased.before;
+
+ @Override
+ public Phased getPhased() {
+ return phased;
+ }
+
@Override
public int getPriority() {
return Integer.MIN_VALUE;
}
- @Override
- public boolean isDataAccessControl() {
- return dataAccessControl;
- }
-
- @Override
- public Set getPermissions() {
- return new HashSet<>(permissions);
- }
-
- @Override
- public Set getActions() {
- return new HashSet<>(actions);
- }
-
- @Override
- public Set getRoles() {
- return new HashSet<>(roles);
- }
-
- @Override
- public Set getUser() {
- return new HashSet<>(user);
- }
-
- @Override
- public Script getScript() {
- return script;
- }
-
- @Override
- public String getMessage() {
- return message;
- }
-
- @Override
- public Logical getLogical() {
- return logical;
- }
-
@Override
public boolean isEmpty() {
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 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 permissions) {
- this.permissions = permissions;
- }
-
- public void setRoles(Set roles) {
- this.roles = roles;
- }
-
- public void setScript(Script script) {
- this.script = script;
- }
-
- public void setUser(Set 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) {
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/EmptyAuthorizeDefinition.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/EmptyAuthorizeDefinition.java
index 844097605..bd73e1516 100644
--- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/EmptyAuthorizeDefinition.java
+++ b/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();
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java
index e4079481d..aaf998634 100644
--- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java
+++ b/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) {
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/MethodProceedCallback.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/MethodProceedCallback.java
new file mode 100644
index 000000000..4ae449737
--- /dev/null
+++ b/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);
+}
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java
index ad16c6a1b..d9308224a 100644
--- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java
+++ b/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));
}
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java
index 50b8e3eb0..602aa5cd2 100644
--- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java
+++ b/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 fields) {
+ if (null == obj) {
+ return;
+ }
+ for (String field : fields) {
+ try {
+ BeanUtilsBean.getInstance().getPropertyUtils().setProperty(obj, field, null);
+ } catch (Exception ignore) {
+
+ }
+ }
+ }
}
diff --git a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldScopeDataAccessHandler.java b/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldScopeDataAccessHandler.java
index 87988a0aa..4131da265 100644
--- a/hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldScopeDataAccessHandler.java
+++ b/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 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 oldParam = entity.getTerms();
- //清空旧的查询条件
- entity.setTerms(new ArrayList<>());
- //添加一个查询条件
- entity.addTerm(createQueryTerm(access))
- //客户端提交的参数 作为嵌套参数
- .nest().setTerms(oldParam);
return true;
}
+ protected boolean propertyInScope(Object obj, String property, Set