Browse Source

Merge branch 'master' of https://github.com/hs-web/hsweb-framework

wangwei 7 years ago
parent
commit
473a354eca
79 changed files with 718 additions and 1141 deletions
  1. 6 1
      hsweb-authorization/hsweb-authorization-api/README.md
  2. 3 0
      hsweb-authorization/hsweb-authorization-api/define.md
  3. 3 3
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessController.java
  4. 2 2
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessHandler.java
  5. 2 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinition.java
  6. 5 7
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/AuthorizingContext.java
  7. 22 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/exception/AccessDenyException.java
  8. 0 19
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/exception/AuthorizationException.java
  9. 55 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/exception/UnAuthorizedException.java
  10. 3 7
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleFieldFilterDataAccessConfig.java
  11. 14 4
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/MemoryUserTokenManager.java
  12. 8 7
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/SimpleUserToken.java
  13. 16 16
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserToken.java
  14. 21 3
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenManager.java
  15. 3 0
      hsweb-authorization/hsweb-authorization-api/token.md
  16. 49 0
      hsweb-authorization/hsweb-authorization-basic/README.md
  17. 5 0
      hsweb-authorization/hsweb-authorization-basic/pom.xml
  18. 13 9
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java
  19. 13 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopMethodAuthorizeDefinitionCustomizerParser.java
  20. 2 2
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopMethodAuthorizeDefinitionParser.java
  21. 59 12
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java
  22. 4 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java
  23. 11 3
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/EmptyAuthorizeDefinition.java
  24. 2 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/AuthorizingHandler.java
  25. 19 18
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java
  26. 2 2
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/CustomDataAccessHandler.java
  27. 4 4
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java
  28. 13 10
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java
  29. 7 9
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldScopeDataAccessHandler.java
  30. 15 21
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/OwnCreatedDataAccessHandler.java
  31. 3 3
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/ScriptDataAccessHandler.java
  32. 2 4
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignOut.java
  33. 5 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenAuthenticationSupplier.java
  34. 2 7
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/WebUserTokenInterceptor.java
  35. 1 34
      hsweb-authorization/hsweb-authorization-shiro/README.md
  36. 0 27
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoConfiguration.java
  37. 1 9
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java
  38. 0 150
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DataAccessAnnotationMethodInterceptor.java
  39. 0 60
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultDataAccessController.java
  40. 0 87
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/ExpressionAnnotationMethodInterceptor.java
  41. 0 42
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/CustomDataAccessHandler.java
  42. 0 86
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/FieldFilterDataAccessHandler.java
  43. 0 114
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/FieldScopeDataAccessHandler.java
  44. 0 129
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/OwnCreatedDataAccessHandler.java
  45. 0 39
      hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/ScriptDataAccessHandler.java
  46. 1 1
      hsweb-boost/hsweb-boost-aop/src/main/java/org/hswebframework/web/boost/aop/context/MethodInterceptorParamContext.java
  47. 2 2
      hsweb-boost/hsweb-boost-aop/src/main/java/org/hswebframework/web/boost/aop/context/MethodInterceptorHolder.java
  48. 2 2
      hsweb-boost/hsweb-boost-validator/hsweb-boost-validator-api/src/main/java/org/hswebframework/web/boost/validator/DuplicateValidator.java
  49. 4 4
      hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java
  50. 16 0
      hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractTreeSortService.java
  51. 0 39
      hsweb-core/src/main/java/org/hswebframework/web/AuthorizeException.java
  52. 0 38
      hsweb-core/src/main/java/org/hswebframework/web/AuthorizeForbiddenException.java
  53. 14 5
      hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java
  54. 2 2
      hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java
  55. 6 10
      hsweb-logging/hsweb-access-logging-api/src/main/java/org/hswebframework/web/logging/AccessLoggerInfo.java
  56. 11 15
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/RestControllerExceptionTranslator.java
  57. 2 4
      hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/resolver/AuthorizationArgumentResolver.java
  58. 3 6
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java
  59. 33 4
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/UserController.java
  60. 7 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorizationSettingService.java
  61. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/pom.xml
  62. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/resources/hsweb-starter.js
  63. 2 5
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/LoginTests.java
  64. 2 2
      hsweb-system/hsweb-system-oauth2-server/hsweb-system-oauth2-server-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2AuthorizeController.java
  65. 3 3
      hsweb-system/hsweb-system-oauth2-server/hsweb-system-oauth2-server-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2UserInfoController.java
  66. 16 3
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/OrganizationalAuthorizationAutoConfiguration.java
  67. 1 1
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/access/DataAccessType.java
  68. 42 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/CustomScope.java
  69. 35 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/CustomScopeDataAccessConfigConvert.java
  70. 28 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/SimpleCustomScopeDataAccessConfig.java
  71. 7 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/SimpleScopeDataAccessConfig.java
  72. 23 27
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/AbstractScopeDataAccessHandler.java
  73. 43 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/CustomScopeHandler.java
  74. 3 2
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/DepartmentScopeDataAccessHandler.java
  75. 3 2
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/AreaScopeDataAccessHandler.java
  76. 3 6
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/OrgScopeDataAccessHandler.java
  77. 2 1
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/PersonScopeDataAccessHandler.java
  78. 3 2
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/PositionScopeDataAccessHandler.java
  79. 2 0
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-service/hsweb-system-organizational-service-simple/src/main/java/org/hswebframework/web/service/organizational/simple/SimplePersonService.java

+ 6 - 1
hsweb-authorization/hsweb-authorization-api/README.md

@@ -1,6 +1,10 @@
 # 权限控制API
 用于权限控制的API接口,支持RBAC权限控制,支持数据级(控制到行,列)权限控制.
 
+[用户令牌管理](token.md)
+
+[权限控制配置](define.md)
+
 # 介绍
 
 以下讲到的类都是基于包:org.hswebframework.web.authorization
@@ -52,4 +56,5 @@ public class CustomAuthorizationSuccessListener implements AuthorizationListener
             System.out.println(authentication.getUser().getName()+"登录啦");
         }
 }
-```
+```
+

+ 3 - 0
hsweb-authorization/hsweb-authorization-api/define.md

@@ -0,0 +1,3 @@
+# 权限配置定义
+
+用于告诉权限框架哪些请求需要进行权限控制,怎么控制.

+ 3 - 3
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessController.java

@@ -1,6 +1,6 @@
 package org.hswebframework.web.authorization.access;
 
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 
 /**
  * 数据级别权限控制器,通过此控制器对当前登录用户进行的操作进行数据级别的权限控制。
@@ -13,8 +13,8 @@ public interface DataAccessController {
     /**
      * 执行权限控制
      * @param access 控制方式以及配置
-     * @param params 当前操作的方法的参数上下文
+     * @param context 权限验证上下文,用于传递验证过程用到的参数
      * @return 授权是否通过
      */
-    boolean doAccess(DataAccessConfig access, MethodInterceptorParamContext params);
+    boolean doAccess(DataAccessConfig access, AuthorizingContext context);
 }

+ 2 - 2
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessHandler.java

@@ -1,6 +1,6 @@
 package org.hswebframework.web.authorization.access;
 
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 
 /**
  * 数据级别权限控制处理器接口,负责处理支持的权限控制配置
@@ -24,5 +24,5 @@ public interface DataAccessHandler {
      * @param context 参数上下文
      * @return 处理结果
      */
-    boolean handle(DataAccessConfig access, MethodInterceptorParamContext context);
+    boolean handle(DataAccessConfig access, AuthorizingContext context);
 }

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

@@ -74,5 +74,7 @@ public interface AuthorizeDefinition {
      */
     Logical getLogical();
 
+    boolean isEmpty();
+
     DataAccessDefinition getDataAccessDefinition();
 }

+ 5 - 7
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/AuthorizingContext.java

@@ -1,8 +1,7 @@
-package org.hswebframework.web.authorization.basic.handler;
+package org.hswebframework.web.authorization.define;
 
 import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.define.AuthorizeDefinition;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
 
 /**
  * 权限控制上下文
@@ -12,8 +11,7 @@ public class AuthorizingContext {
 
     private Authentication authentication;
 
-    private MethodInterceptorParamContext paramContext;
-
+    private MethodInterceptorContext paramContext;
 
     public AuthorizeDefinition getDefinition() {
         return definition;
@@ -31,11 +29,11 @@ public class AuthorizingContext {
         this.authentication = authentication;
     }
 
-    public MethodInterceptorParamContext getParamContext() {
+    public MethodInterceptorContext getParamContext() {
         return paramContext;
     }
 
-    public void setParamContext(MethodInterceptorParamContext paramContext) {
+    public void setParamContext(MethodInterceptorContext paramContext) {
         this.paramContext = paramContext;
     }
 }

+ 22 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/exception/AccessDenyException.java

@@ -0,0 +1,22 @@
+package org.hswebframework.web.authorization.exception;
+
+/**
+ * 权限验证异常
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public class AccessDenyException extends RuntimeException {
+
+    public AccessDenyException() {
+        this("{access_deny}");
+    }
+
+    public AccessDenyException(String message) {
+        super(message);
+    }
+
+    public AccessDenyException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}

+ 0 - 19
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/exception/AuthorizationException.java

@@ -1,19 +0,0 @@
-package org.hswebframework.web.authorization.exception;
-
-/**
- * 权限验证异常
- * @author zhouhao
- */
-public class AuthorizationException extends RuntimeException {
-
-    public AuthorizationException() {
-    }
-
-    public AuthorizationException(String message) {
-        super(message);
-    }
-
-    public AuthorizationException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}

+ 55 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/exception/UnAuthorizedException.java

@@ -0,0 +1,55 @@
+/*
+ *
+ *  * Copyright 2016 http://www.hswebframework.org
+ *  *
+ *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  * you may not use this file except in compliance with the License.
+ *  * You may obtain a copy of the License at
+ *  *
+ *  *     http://www.apache.org/licenses/LICENSE-2.0
+ *  *
+ *  * Unless required by applicable law or agreed to in writing, software
+ *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  * See the License for the specific language governing permissions and
+ *  * limitations under the License.
+ *
+ */
+
+package org.hswebframework.web.authorization.exception;
+
+import org.hswebframework.web.authorization.token.TokenState;
+
+/**
+ * 未授权异常
+ *
+ * @author zhouhao
+ * @since 3.0
+ */
+public class UnAuthorizedException extends RuntimeException {
+    private static final long serialVersionUID = 2422918455013900645L;
+
+    private TokenState state;
+
+    public UnAuthorizedException() {
+        this(TokenState.expired);
+    }
+
+    public UnAuthorizedException(TokenState state) {
+        this("{un_authorization}", state);
+    }
+
+    public UnAuthorizedException(String message, TokenState state) {
+        super(message);
+        this.state = state;
+    }
+
+    public UnAuthorizedException(String message, TokenState state, Throwable cause) {
+        super(message, cause);
+        this.state = state;
+    }
+
+    public TokenState getState() {
+        return state;
+    }
+}

+ 3 - 7
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleFieldFilterDataAccessConfig.java

@@ -6,6 +6,8 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 
+import static org.hswebframework.web.authorization.access.DataAccessConfig.DefaultType.DENY_FIELDS;
+
 /**
  * 默认配置实现
  *
@@ -16,8 +18,6 @@ import java.util.Set;
 public class SimpleFieldFilterDataAccessConfig extends AbstractDataAccessConfig implements FieldFilterDataAccessConfig {
     private Set<String> fields;
 
-    private String type;
-
     public SimpleFieldFilterDataAccessConfig() {
     }
 
@@ -36,10 +36,6 @@ public class SimpleFieldFilterDataAccessConfig extends AbstractDataAccessConfig
 
     @Override
     public String getType() {
-        return type;
-    }
-
-    public void setType(String type) {
-        this.type = type;
+        return DENY_FIELDS;
     }
 }

+ 14 - 4
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/MemoryUserTokenManager.java

@@ -18,8 +18,8 @@
 
 package org.hswebframework.web.authorization.token;
 
-import org.hswebframework.web.authorization.token.event.UserSignInEvent;
 import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher;
+import org.hswebframework.web.authorization.token.event.UserSignInEvent;
 
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
@@ -69,7 +69,6 @@ public class MemoryUserTokenManager implements UserTokenManager {
         if (null == detail) return null;
         if (System.currentTimeMillis() - detail.getLastRequestTime() > timeout * 1000) {
             detail.setState(TokenState.expired);
-            // signOutByToken(detail.getToken());
             return detail;
         }
         return detail;
@@ -97,9 +96,8 @@ public class MemoryUserTokenManager implements UserTokenManager {
 
     @Override
     public boolean tokenIsLoggedIn(String token) {
-        UserToken userToken = getByToken(token);
 
-        return userToken != null && userToken.isEffective();
+        return getByToken(token) != null;
     }
 
     @Override
@@ -141,6 +139,18 @@ public class MemoryUserTokenManager implements UserTokenManager {
         tokenUserStorage.remove(token);
     }
 
+    @Override
+    public void changeTokenState(String token, TokenState state) {
+        SimpleUserToken userToken = getByToken(token);
+        if (null != userToken)
+            userToken.setState(state);
+    }
+
+    @Override
+    public void changeUserState(String user, TokenState state) {
+        getByUserId(user).forEach(token -> changeTokenState(token.getToken(), state));
+    }
+
     @Override
     public UserToken signIn(String token, String userId) {
         SimpleUserToken detail = new SimpleUserToken(userId, token);

+ 8 - 7
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/SimpleUserToken.java

@@ -4,8 +4,9 @@ import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * 用户令牌信息
- * @since 3.0
+ *
  * @author zhouhao
+ * @since 3.0
  */
 public class SimpleUserToken implements UserToken {
 
@@ -13,13 +14,13 @@ public class SimpleUserToken implements UserToken {
 
     private String token;
 
-    private TokenState state;
+    private volatile TokenState state;
 
-    private AtomicLong requestTimesCounter=new AtomicLong(0);
+    private AtomicLong requestTimesCounter = new AtomicLong(0);
 
-    private volatile long lastRequestTime=System.currentTimeMillis();
+    private volatile long lastRequestTime = System.currentTimeMillis();
 
-    private volatile long firstRequestTime=System.currentTimeMillis();
+    private volatile long firstRequestTime = System.currentTimeMillis();
 
     private volatile long requestTimes;
 
@@ -86,8 +87,8 @@ public class SimpleUserToken implements UserToken {
         requestTimesCounter.set(requestTimes);
     }
 
-    void touch(){
+    void touch() {
         requestTimesCounter.addAndGet(1);
-        lastRequestTime=System.currentTimeMillis();
+        lastRequestTime = System.currentTimeMillis();
     }
 }

+ 16 - 16
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserToken.java

@@ -2,74 +2,74 @@ package org.hswebframework.web.authorization.token;
 
 
 import org.hswebframework.web.authorization.User;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 
 import java.io.Serializable;
 
 /**
  * 用户的token信息
+ *
  * @author zhouhao
  * @since 3.0
  */
 public interface UserToken extends Serializable, Comparable<UserToken> {
     /**
-     *
      * @return 用户id
-     * @see  User#getId()
+     * @see User#getId()
      */
     String getUserId();
 
     /**
-     *
      * @return token
      */
     String getToken();
 
     /**
-     *
      * @return 请求总次数
      */
     long getRequestTimes();
 
     /**
-     *
      * @return 最后一次请求时间
      */
     long getLastRequestTime();
 
     /**
-     *
      * @return 首次请求时间
      */
     long getSignInTime();
 
     /**
-     *
      * @return 令牌状态
      */
     TokenState getState();
 
     /**
-     *
      * @return 是否正常
      */
-    default boolean isEffective(){
-        return getState()==TokenState.effective;
+    default boolean isEffective() {
+        return getState() == TokenState.effective;
     }
 
     /**
-     *
      * @return 是否已过期
      */
-    default boolean isExpired(){
-        return getState()==TokenState.expired;
+    default boolean isExpired() {
+        return getState() == TokenState.expired;
     }
 
     /**
-     *
      * @return 是否离线
      */
-    default boolean isOffline(){
-        return getState()==TokenState.offline;
+    default boolean isOffline() {
+        return getState() == TokenState.offline;
+    }
+
+    default boolean validate() {
+        if (!isEffective()) {
+            throw new UnAuthorizedException(getState());
+        }
+        return true;
     }
 
     @Override

+ 21 - 3
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenManager.java

@@ -38,6 +38,7 @@ public interface UserTokenManager {
 
     /**
      * 根据用户id,获取全部令牌信息,如果设置了不能跨地点登陆,返回值只可能是{@code null}或者size为1的list
+     *
      * @param userId 用户id
      * @return 授权信息
      */
@@ -50,7 +51,6 @@ public interface UserTokenManager {
     boolean userIsLoggedIn(String userId);
 
     /**
-     *
      * @param token token
      * @return token是否已登记
      */
@@ -62,7 +62,6 @@ public interface UserTokenManager {
     long totalUser();
 
     /**
-     *
      * @return 总token数量
      */
     long totalToken();
@@ -81,19 +80,38 @@ public interface UserTokenManager {
 
     /**
      * 根据token删除
+     *
      * @param token
      */
     void signOutByToken(String token);
 
     /**
-     * 登记一个用户的token
+     * 修改userId的状态
+     *
+     * @param userId userId
+     * @param state  状态
+     */
+    void changeUserState(String userId, TokenState state);
+
+    /**
+     * 修改token的状态
+     *
      * @param token token
+     * @param state 状态
+     */
+    void changeTokenState(String token, TokenState state);
+
+    /**
+     * 登记一个用户的token
+     *
+     * @param token  token
      * @param userId 用户id
      */
     UserToken signIn(String token, String userId);
 
     /**
      * 更新token,使其不过期
+     *
      * @param token token
      */
     void touch(String token);

+ 3 - 0
hsweb-authorization/hsweb-authorization-api/token.md

@@ -0,0 +1,3 @@
+# 用户令牌管理
+用于管理已授权的用户,并这些用户进行操作,如: 统计人数,踢下线,禁止多地点同时登录等操作
+

+ 49 - 0
hsweb-authorization/hsweb-authorization-basic/README.md

@@ -0,0 +1,49 @@
+# 权限控制基础实现
+
+1. 实现RBAC权限控制
+2. 实现数据权限控制
+3. 可动态进行权限配置设置
+
+默认仅提供了aop方式的权限控制,控制逻辑如下:
+1. `AopAuthorizingController` aop拦截所有controller方法(注解了:`Controller`或者`RestController`的类的方法)
+2. 在客户端发起请求的时候,将拦截到的方法信息(`MethodInterceptorContext`)传给权限定义解析器(`AopMethodAuthorizeDefinitionParser`)
+进行解析
+3. 框架默认实现的解析器会先调用所有的`AopMethodAuthorizeDefinitionCustomizerParser`获取自定义的配置(实现`AopMethodAuthorizeDefinitionCustomizerParser`接口并注入到spring即可,自定义未进行缓存,请自行实现缓存策略)
+如果没有,则获取缓存,如果缓存不存在就开始解析方法以及类上的注解,并放入缓存后返回权限配
+4. 如果解析器返回的结果不为空,并且用户已经登录,则调用`AuthorizingHandler`进行权限控制
+5. 默认的权限控制实现`DefaultAuthorizingHandler`,将分别进行RBAC,数据权限,表达式方式的权限控制.
+6. 如果授权未通过,则抛出`AccessDenyException`异常
+
+## 授权
+使用`hsweb-authorization-api`提供的监听器,类`UserOnSignIn`监听用户授权事件`AuthorizationSuccessEvent`
+当用户完成授权(授权方式可自行实现或者使用框架默认的授权方式,主要触发该事件即可).授权通过后会触发该事件.流程如下
+
+1. 完成授权,触发`AuthorizationSuccessEvent`
+2. `UserOnSignIn` 收到`AuthorizationSuccessEvent`事件,获取参数`token_type`(默认为`sessionId`),以及授权信息
+3. 根据`token_type` 生成token.
+4. 将token和授权信息中的userId注册到`UserTokenManager`
+5. 将token返回给授权接口
+
+## 注销
+与授权同理,类`UserOnSignOut`监听`AuthorizationExitEvent` ,当触发事件后,调用`UserTokenManager`移除当前登录的token信息
+
+## rbac权限控制
+默认对注解`Authorize`进行实现,具体功能,请查看源代码
+
+## 数据权限
+原理: 通过用户的权限信息,对aop拦截到的参数进行操作
+
+约束: 对方法的参数有要求,如动态查询需要有参数`QueryParamEntity`,controller需要实现`hsweb-commons-controller`中提供的通用controller等
+
+例如:用户设置了 机构管理权限(org)只能查询(query)自己和下属的机构.
+通过获取拦截到方法的动态查询参数`QueryParamEntity`,对参数进行重构,
+客户端的查询条件翻译为sql:
+```sql
+where name like ? or full_name like
+```     
+     
+重构后为:
+```sql
+--u_id in (用户可访问的机构id)
+where u_id in(?,?,?) and (name like ? or full_name like)
+```

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

@@ -50,6 +50,11 @@
             <version>2.5</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-entity</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 13 - 9
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java

@@ -3,12 +3,12 @@ package org.hswebframework.web.authorization.basic.aop;
 import org.aopalliance.intercept.MethodInterceptor;
 import org.hswebframework.web.AopUtils;
 import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.basic.handler.AuthorizingContext;
+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.exception.AuthorizationException;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
 import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RestController;
@@ -25,16 +25,20 @@ public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor
 
             MethodInterceptorHolder holder = MethodInterceptorHolder.create(methodInvocation);
 
-            MethodInterceptorParamContext paramContext = holder.createParamContext();
+            MethodInterceptorContext paramContext = holder.createParamContext();
 
             AuthorizeDefinition definition = aopMethodAuthorizeDefinitionParser.parse(paramContext);
 
             if (null != definition) {
-                AuthorizingContext context = new AuthorizingContext();
-                context.setAuthentication(Authentication.current().orElseThrow(AuthorizationException::new));
-                context.setDefinition(definition);
-                context.setParamContext(paramContext);
-                authorizingHandler.handle(context);
+                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);
+                }
             }
             return methodInvocation.proceed();
         });

+ 13 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopMethodAuthorizeDefinitionCustomizerParser.java

@@ -0,0 +1,13 @@
+package org.hswebframework.web.authorization.basic.aop;
+
+import org.hswebframework.web.authorization.define.AuthorizeDefinition;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
+
+/**
+ * 自定义权限控制定义,在拦截到方法后,优先使用此接口来获取权限控制方式
+ * @see AuthorizeDefinition
+ * @author zhouhao
+ */
+public interface AopMethodAuthorizeDefinitionCustomizerParser {
+    AuthorizeDefinition parse(MethodInterceptorContext context);
+}

+ 2 - 2
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopMethodAuthorizeDefinitionParser.java

@@ -1,7 +1,7 @@
 package org.hswebframework.web.authorization.basic.aop;
 
 import org.hswebframework.web.authorization.define.AuthorizeDefinition;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
 
 /**
  * 权限控制定义解析器,用于解析被拦截的请求是否需要进行权限控制,以及权限控制的方式
@@ -17,5 +17,5 @@ public interface AopMethodAuthorizeDefinitionParser {
      * @param paramContext 被拦截的方法上下文
      * @return 权限控制定义, 如果不进行权限控制则返回{@code null}
      */
-    AuthorizeDefinition parse(MethodInterceptorParamContext paramContext);
+    AuthorizeDefinition parse(MethodInterceptorContext paramContext);
 }

+ 59 - 12
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java

@@ -7,9 +7,14 @@ import org.hswebframework.web.authorization.annotation.RequiresExpression;
 import org.hswebframework.web.authorization.basic.define.DefaultBasicAuthorizeDefinition;
 import org.hswebframework.web.authorization.basic.define.EmptyAuthorizeDefinition;
 import org.hswebframework.web.authorization.define.AuthorizeDefinition;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.CollectionUtils;
 
 import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -23,14 +28,31 @@ import java.util.concurrent.ConcurrentHashMap;
 
 public class DefaultAopMethodAuthorizeDefinitionParser implements AopMethodAuthorizeDefinitionParser {
 
-    private Map<Method, AuthorizeDefinition> cache = new ConcurrentHashMap<>();
+    private Map<CacheKey, AuthorizeDefinition> cache = new ConcurrentHashMap<>();
+
+
+    private List<AopMethodAuthorizeDefinitionCustomizerParser> parserCustomers;
+
+    @Autowired(required = false)
+    public void setParserCustomers(List<AopMethodAuthorizeDefinitionCustomizerParser> parserCustomers) {
+        this.parserCustomers = parserCustomers;
+    }
 
     @Override
-    public AuthorizeDefinition parse(MethodInterceptorParamContext paramContext) {
+    public AuthorizeDefinition parse(MethodInterceptorContext paramContext) {
+        CacheKey key = buildCacheKey(paramContext);
 
-        AuthorizeDefinition definition = cache.get(paramContext.getMethod());
+        AuthorizeDefinition definition = cache.get(key);
         if (definition != null) return definition instanceof EmptyAuthorizeDefinition ? null : definition;
-
+        //使用自定义
+        if (!CollectionUtils.isEmpty(parserCustomers)) {
+            definition = parserCustomers.stream()
+                    .map(customer -> customer.parse(paramContext))
+                    .findAny().orElse(null);
+            if (definition != null) {
+                return definition;
+            }
+        }
 
         Authorize classAuth = AopUtils.findAnnotation(paramContext.getTarget().getClass(), Authorize.class);
         Authorize methodAuth = AopUtils.findMethodAnnotation(paramContext.getTarget().getClass(), paramContext.getMethod(), Authorize.class);
@@ -40,29 +62,54 @@ public class DefaultAopMethodAuthorizeDefinitionParser implements AopMethodAutho
         RequiresExpression expression = AopUtils.findAnnotation(paramContext.getTarget().getClass(), RequiresExpression.class);
 
         if (classAuth == null && methodAuth == null && classDataAccess == null && methodDataAccess == null && expression == null) {
-            cache.put(paramContext.getMethod(), EmptyAuthorizeDefinition.instance);
+            cache.put(key, EmptyAuthorizeDefinition.instance);
             return null;
         }
 
-        if (methodAuth != null && methodAuth.ignore()) {
-            cache.put(paramContext.getMethod(), EmptyAuthorizeDefinition.instance);
+        if ((methodAuth != null && methodAuth.ignore()) || (classAuth != null && classAuth.ignore())) {
+            cache.put(key, EmptyAuthorizeDefinition.instance);
             return null;
         }
 
-
         DefaultBasicAuthorizeDefinition authorizeDefinition = new DefaultBasicAuthorizeDefinition();
 
-        authorizeDefinition.put(classAuth);
+        if (methodAuth == null || methodAuth.merge())
+            authorizeDefinition.put(classAuth);
+
         authorizeDefinition.put(methodAuth);
 
         authorizeDefinition.put(expression);
 
         authorizeDefinition.put(classDataAccess);
-        authorizeDefinition.put(methodDataAccess);
 
-        cache.put(paramContext.getMethod(), authorizeDefinition);
+        authorizeDefinition.put(methodDataAccess);
 
+        cache.put(key, authorizeDefinition);
         return authorizeDefinition;
     }
 
+    public CacheKey buildCacheKey(MethodInterceptorContext context) {
+        return new CacheKey(ClassUtils.getUserClass(context.getTarget()), context.getMethod());
+    }
+
+    class CacheKey {
+        private Class  type;
+        private Method method;
+
+        public CacheKey(Class type, Method method) {
+            this.type = type;
+            this.method = method;
+        }
+
+        @Override
+        public int hashCode() {
+            return Arrays.asList(type, method).hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj != null && this.hashCode() == obj.hashCode();
+        }
+    }
+
 }

+ 4 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java

@@ -80,6 +80,10 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
         return logical;
     }
 
+    public boolean isEmpty() {
+        return permissions.isEmpty() && roles.isEmpty() && user.isEmpty() && script == null && dataAccessDefinition == null;
+    }
+
     @Override
     public DataAccessDefinition getDataAccessDefinition() {
         return dataAccessDefinition;

+ 11 - 3
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/EmptyAuthorizeDefinition.java

@@ -12,11 +12,14 @@ import java.util.Set;
  */
 public class EmptyAuthorizeDefinition implements AuthorizeDefinition {
 
-    public static final EmptyAuthorizeDefinition instance=new EmptyAuthorizeDefinition();
-    private EmptyAuthorizeDefinition(){}
+    public static final EmptyAuthorizeDefinition instance = new EmptyAuthorizeDefinition();
+
+    private EmptyAuthorizeDefinition() {
+    }
+
     @Override
     public int getPriority() {
-       throw new UnsupportedOperationException();
+        throw new UnsupportedOperationException();
     }
 
     @Override
@@ -59,6 +62,11 @@ public class EmptyAuthorizeDefinition implements AuthorizeDefinition {
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public boolean isEmpty() {
+        return true;
+    }
+
     @Override
     public DataAccessDefinition getDataAccessDefinition() {
         throw new UnsupportedOperationException();

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

@@ -1,5 +1,7 @@
 package org.hswebframework.web.authorization.basic.handler;
 
+import org.hswebframework.web.authorization.define.AuthorizingContext;
+
 /**
  * aop方式权限控制处理器
  * @author zhouhao

+ 19 - 18
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java

@@ -10,8 +10,9 @@ import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessController;
 import org.hswebframework.web.authorization.annotation.Logical;
 import org.hswebframework.web.authorization.define.AuthorizeDefinition;
-import org.hswebframework.web.authorization.exception.AuthorizationException;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
+import org.hswebframework.web.authorization.exception.AccessDenyException;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,21 +48,21 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         handleRdac(context.getAuthentication(), context.getDefinition());
 
         //进行数据权限控制
-        handleDataAccess(context.getAuthentication(), context.getDefinition(), context.getParamContext());
+        handleDataAccess(context);
 
         //表达式权限控制
         handleExpression(context.getAuthentication(), context.getDefinition(), context.getParamContext());
 
     }
 
-    protected void handleDataAccess(Authentication authentication, AuthorizeDefinition definition, MethodInterceptorParamContext paramContext) {
+    protected void handleDataAccess(AuthorizingContext context) {
         if (dataAccessController == null) {
-            logger.warn("dataAccessController is null,skip data access control!");
+            logger.warn("dataAccessController is null,skip result access control!");
             return;
         }
-        List<Permission> permission = authentication.getPermissions()
+        List<Permission> permission = context.getAuthentication().getPermissions()
                 .stream()
-                .filter(per -> definition.getPermissions().contains(per.getId()))
+                .filter(per -> context.getDefinition().getPermissions().contains(per.getId()))
                 .collect(Collectors.toList());
 
         DataAccessController finalAccessController = dataAccessController;
@@ -70,51 +71,51 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         Set<DataAccessConfig> accesses = permission
                 .stream().map(Permission::getDataAccesses)
                 .flatMap(Collection::stream)
-                .filter(access -> definition.getActions().contains(access.getAction()))
+                .filter(access -> context.getDefinition().getActions().contains(access.getAction()))
                 .collect(Collectors.toSet());
         //无规则,则代表不进行控制
         if (accesses.isEmpty()) return;
         //单个规则验证函数
-        Function<Predicate<DataAccessConfig>, Boolean> function =
-                definition.getLogical() == Logical.AND ?
-                        accesses.stream()::allMatch : accesses.stream()::anyMatch;
+        Function<Predicate<DataAccessConfig>, Boolean> function = accesses.stream()::allMatch;
         //调用控制器进行验证
-        boolean isAccess = function.apply(access -> finalAccessController.doAccess(access, paramContext));
+        boolean isAccess = function.apply(access -> finalAccessController.doAccess(access, context));
         if (!isAccess) {
-            throw new AuthorizationException(definition.getMessage());
+            throw new AccessDenyException(context.getDefinition().getMessage());
         }
 
     }
 
-    protected void handleExpression(Authentication authentication, AuthorizeDefinition definition, MethodInterceptorParamContext paramContext) {
+    protected void handleExpression(Authentication authentication, AuthorizeDefinition definition, MethodInterceptorContext paramContext) {
         if (definition.getScript() != null) {
             String scriptId = DigestUtils.md5Hex(definition.getScript().getScript());
 
             DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(definition.getScript().getLanguage());
             if (null == engine) {
-                throw new AuthorizationException("{unknown_engine}:" + definition.getScript().getLanguage());
+                throw new AccessDenyException("{unknown_engine}:" + definition.getScript().getLanguage());
             }
             if (!engine.compiled(scriptId)) {
                 try {
                     engine.compile(scriptId, definition.getScript().getScript());
                 } catch (Exception e) {
                     logger.error("express compile error", e);
-                    throw new AuthorizationException("{expression_error}");
+                    throw new AccessDenyException("{expression_error}");
                 }
             }
             Map<String, Object> var = new HashMap<>(paramContext.getParams());
             var.put("auth", authentication);
             Object success = engine.execute(scriptId, var).get();
             if (!(success instanceof Boolean) || !((Boolean) success)) {
-                throw new AuthorizationException(definition.getMessage());
+                throw new AccessDenyException(definition.getMessage());
             }
         }
     }
 
     protected void handleRdac(Authentication authentication, AuthorizeDefinition definition) {
         boolean access = true;
+        //多个设置时的判断逻辑
         Logical logical = definition.getLogical() == Logical.DEFAULT ? Logical.OR : definition.getLogical();
         boolean logicalIsOr = logical == Logical.OR;
+
         Set<String> permissionsDef = definition.getPermissions();
         Set<String> actionsDef = definition.getActions();
         Set<String> rolesDef = definition.getRoles();
@@ -170,7 +171,7 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
             access = func.apply(authentication.getUser().getUsername()::equals);
         }
         if (!access) {
-            throw new AuthorizationException(definition.getMessage());
+            throw new AccessDenyException(definition.getMessage());
         }
     }
 }

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

@@ -21,7 +21,7 @@ package org.hswebframework.web.authorization.basic.handler.access;
 import org.hswebframework.web.authorization.access.CustomDataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 
 /**
  * 当配置为自定义处理器时(实现{@link CustomDataAccessConfig }接口),此处理器生效
@@ -37,7 +37,7 @@ public class CustomDataAccessHandler implements DataAccessHandler {
     }
 
     @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
+    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
         CustomDataAccessConfig custom = ((CustomDataAccessConfig) access);
         return custom.getController().doAccess(access, context);
     }

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

@@ -3,7 +3,7 @@ package org.hswebframework.web.authorization.basic.handler.access;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessController;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 
 import java.util.LinkedList;
 import java.util.List;
@@ -36,12 +36,12 @@ public final class DefaultDataAccessController implements DataAccessController {
     }
 
     @Override
-    public boolean doAccess(DataAccessConfig access, MethodInterceptorParamContext params) {
-        if (parent != null) parent.doAccess(access, params);
+    public boolean doAccess(DataAccessConfig access, AuthorizingContext context) {
+        if (parent != null) parent.doAccess(access, context);
         return handlers.stream()
                 // TODO: 17-3-28 可以换成access对应的handler以提高效率
                 .filter(handler -> handler.isSupport(access))
-                .allMatch(handler -> handler.handle(access, params));
+                .allMatch(handler -> handler.handle(access, context));
     }
 
     public DefaultDataAccessController addHandler(DataAccessHandler handler) {

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

@@ -5,13 +5,15 @@ import org.hswebframework.web.authorization.Permission;
 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.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.commons.model.Model;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Map;
+
 /**
  * 数据权限字段过滤处理,目前仅支持deny. {@link DataAccessConfig.DefaultType#DENY_FIELDS}
  *
@@ -22,11 +24,11 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
 
     @Override
     public boolean isSupport(DataAccessConfig access) {
-        return access instanceof FieldFilterDataAccessConfig && DataAccessConfig.DefaultType.DENY_FIELDS.equals(access.getType());
+        return access instanceof FieldFilterDataAccessConfig;
     }
 
     @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
+    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
         FieldFilterDataAccessConfig filterDataAccessConfig = ((FieldFilterDataAccessConfig) access);
 
         switch (access.getAction()) {
@@ -48,10 +50,11 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
      * @see BeanUtilsBean
      * @see org.apache.commons.beanutils.PropertyUtilsBean
      */
-    protected boolean doUpdateAccess(FieldFilterDataAccessConfig accesses, MethodInterceptorParamContext params) {
-        Object supportParam = params.getParams().values().stream()
-                .filter(param -> (param instanceof Entity) | (param instanceof Model))
-                .findAny().orElse(null);
+    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))
+                .findAny()
+                .orElse(null);
         if (null != supportParam) {
             for (String field : accesses.getFields()) {
                 try {
@@ -64,14 +67,14 @@ public class FieldFilterDataAccessHandler implements DataAccessHandler {
                 }
             }
         } else {
-            logger.warn("doUpdateAccess skip ,because can not found any entity in param!");
+            logger.warn("doUpdateAccess skip ,because can not found any support entity in param!");
         }
         return true;
     }
 
 
-    protected boolean doQueryAccess(FieldFilterDataAccessConfig access, MethodInterceptorParamContext context) {
-        QueryParamEntity entity = context.getParams()
+    protected boolean doQueryAccess(FieldFilterDataAccessConfig access, AuthorizingContext context) {
+        QueryParamEntity entity = context.getParamContext().getParams()
                 .values().stream()
                 .filter(QueryParamEntity.class::isInstance)
                 .map(QueryParamEntity.class::cast)

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

@@ -8,8 +8,7 @@ import org.hswebframework.web.authorization.Permission;
 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.annotation.RequiresDataAccess;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.QueryController;
 import org.hswebframework.web.service.QueryService;
@@ -33,9 +32,9 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
     }
 
     @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
+    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
         FieldScopeDataAccessConfig own = ((FieldScopeDataAccessConfig) access);
-        Object controller = context.getTarget();
+        Object controller = context.getParamContext().getTarget();
         if (controller != null) {
             switch (access.getAction()) {
                 case Permission.ACTION_QUERY:
@@ -55,10 +54,9 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
     }
 
     @SuppressWarnings("unchecked")
-    protected boolean doRWAccess(FieldScopeDataAccessConfig access, MethodInterceptorParamContext context, Object controller) {
+    protected boolean doRWAccess(FieldScopeDataAccessConfig access, AuthorizingContext context, Object controller) {
         //获取注解
-        RequiresDataAccess dataAccess = context.getAnnotation(RequiresDataAccess.class);
-        Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
+        Object id = context.getParamContext().<String>getParameter(context.getDefinition().getDataAccessDefinition().getIdParameterName()).orElse(null);
         //通过QueryController获取QueryService
         //然后调用selectByPk 查询旧的数据,进行对比
         if (controller instanceof QueryController) {
@@ -80,8 +78,8 @@ public class FieldScopeDataAccessHandler implements DataAccessHandler {
     }
 
 
-    protected boolean doQueryAccess(FieldScopeDataAccessConfig access, MethodInterceptorParamContext context) {
-        QueryParamEntity entity = context.getParams()
+    protected boolean doQueryAccess(FieldScopeDataAccessConfig access, AuthorizingContext context) {
+        QueryParamEntity entity = context.getParamContext().getParams()
                 .values().stream()
                 .filter(QueryParamEntity.class::isInstance)
                 .map(QueryParamEntity.class::cast)

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

@@ -2,14 +2,11 @@ package org.hswebframework.web.authorization.basic.handler.access;
 
 import org.hsweb.ezorm.core.param.Term;
 import org.hswebframework.utils.ClassUtils;
-import org.hswebframework.web.AuthorizeException;
-import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.Permission;
 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.annotation.RequiresDataAccess;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.RecordCreationEntity;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
@@ -35,9 +32,9 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
     }
 
     @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
+    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
         OwnCreatedDataAccessConfig own = ((OwnCreatedDataAccessConfig) access);
-        Object controller = context.getTarget();
+        Object controller = context.getParamContext().getTarget();
         if (controller != null) {
             switch (access.getAction()) {
                 case Permission.ACTION_QUERY:
@@ -45,9 +42,9 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
                 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 data
+                    //put creator_id to result
                     return putCreatorId(own, context);
                 default:
                     logger.warn("action: {} not support now!", access.getAction());
@@ -58,16 +55,14 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
         return true;
     }
 
-    public boolean putCreatorId(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context) {
-        RecordCreationEntity entity = context.getParams()
+    public boolean putCreatorId(OwnCreatedDataAccessConfig access, AuthorizingContext context) {
+        RecordCreationEntity entity = context.getParamContext().getParams()
                 .values().stream()
                 .filter(RecordCreationEntity.class::isInstance)
                 .map(RecordCreationEntity.class::cast)
                 .findAny().orElse(null);
         if (entity != null) {
-            entity.setCreatorId(Authentication.current()
-                    .orElseThrow(AuthorizeException::new)
-                    .getUser().getId());
+            entity.setCreatorId(context.getAuthentication().getUser().getId());
         } else {
             logger.warn("try put creatorId property,but not found any RecordCreationEntity!");
         }
@@ -75,10 +70,9 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
     }
 
     @SuppressWarnings("unchecked")
-    protected boolean doRWAccess(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context, Object controller) {
+    protected boolean doRWAccess(OwnCreatedDataAccessConfig access, AuthorizingContext context, Object controller) {
         //获取注解
-        RequiresDataAccess dataAccess = context.getAnnotation(RequiresDataAccess.class);
-        Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
+        Object id = context.getParamContext().<String>getParameter(context.getDefinition().getDataAccessDefinition().getIdParameterName()).orElse(null);
         //通过QueryController获取QueryService
         //然后调用selectByPk 查询旧的数据,进行对比
         if (controller instanceof QueryController) {
@@ -88,7 +82,7 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
                 QueryService<RecordCreationEntity, Object> queryService =
                         ((QueryController<RecordCreationEntity, Object, Entity>) controller).getService();
                 RecordCreationEntity oldData = queryService.selectByPk(id);
-                if (oldData != null && !Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId().equals(oldData.getCreatorId())) {
+                if (oldData != null && !context.getAuthentication().getUser().getId().equals(oldData.getCreatorId())) {
                     return false;
                 }
             }
@@ -96,8 +90,8 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
         return true;
     }
 
-    protected boolean doQueryAccess(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context) {
-        Entity entity = context.getParams()
+    protected boolean doQueryAccess(OwnCreatedDataAccessConfig access, AuthorizingContext context) {
+        Entity entity = context.getParamContext().getParams()
                 .values().stream()
                 .filter(Entity.class::isInstance)
                 .map(Entity.class::cast)
@@ -116,11 +110,11 @@ public class OwnCreatedDataAccessHandler implements DataAccessHandler {
             queryParamEntity.setTerms(new ArrayList<>());
             //添加一个查询条件
             queryParamEntity
-                    .where(RecordCreationEntity.creatorId, Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId())
+                    .where(RecordCreationEntity.creatorId,context.getAuthentication().getUser().getId())
                     //客户端提交的参数 作为嵌套参数
                     .nest().setTerms(oldParam);
         } else if (entity instanceof RecordCreationEntity) {
-            ((RecordCreationEntity) entity).setCreatorId(Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId());
+            ((RecordCreationEntity) entity).setCreatorId(context.getAuthentication().getUser().getId());
         } else {
             logger.warn("try validate query access,but entity not support, QueryParamEntity and RecordCreationEntity support now!");
         }

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

@@ -8,7 +8,7 @@ import org.hswebframework.web.BusinessException;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
 import org.hswebframework.web.authorization.access.ScriptDataAccessConfig;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 
 /**
  * TODO 完成注释
@@ -22,7 +22,7 @@ public class ScriptDataAccessHandler implements DataAccessHandler {
     }
 
     @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
+    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
         ScriptDataAccessConfig dataAccess = ((ScriptDataAccessConfig) access);
         DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(dataAccess.getScriptLanguage());
         if (engine == null) throw new UnsupportedOperationException(dataAccess.getScriptLanguage() + " {not_support}");
@@ -31,7 +31,7 @@ public class ScriptDataAccessHandler implements DataAccessHandler {
             if (!engine.compiled(scriptId)) {
                 engine.compile(scriptId, dataAccess.getScript());
             }
-            Object success = engine.execute(scriptId, context.getParams()).getIfSuccess();
+            Object success = engine.execute(scriptId, context.getParamContext().getParams()).getIfSuccess();
             return StringUtils.isTrue(success);
         } catch (Exception e) {
             throw new BusinessException("{script_error}", e);

+ 2 - 4
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignOut.java

@@ -1,7 +1,5 @@
 package org.hswebframework.web.authorization.basic.web;
 
-import org.hswebframework.web.ThreadLocalUtils;
-import org.hswebframework.web.WebUtil;
 import org.hswebframework.web.authorization.listener.AuthorizationListener;
 import org.hswebframework.web.authorization.listener.event.AuthorizationExitEvent;
 import org.hswebframework.web.authorization.token.UserToken;
@@ -25,7 +23,7 @@ public class UserOnSignOut implements AuthorizationListener<AuthorizationExitEve
     }
 
     protected String geToken() {
-        // TODO: 17-8-16 更多创建方式
-        return ThreadLocalUtils.<UserToken>get(UserToken.class.getName()).getToken();
+        UserToken token = UserTokenHolder.currentToken();
+        return null != token ? token.getToken() : null;
     }
 }

+ 5 - 1
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenAuthenticationSupplier.java

@@ -31,6 +31,10 @@ public class UserTokenAuthenticationSupplier implements AuthenticationSupplier {
 
     @Override
     public Authentication get() {
-        return ThreadLocalUtils.get(Authentication.class.getName(), () -> get(Optional.ofNullable(getCurrentUserToken()).map(UserToken::getUserId).orElse(null)));
+        return ThreadLocalUtils.get(Authentication.class.getName(), () ->
+                get(Optional.ofNullable(getCurrentUserToken())
+                        .filter(UserToken::validate) //验证token,如果不是正常状态,将会抛出异常
+                        .map(UserToken::getUserId)
+                        .orElse(null)));
     }
 }

+ 2 - 7
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/WebUserTokenInterceptor.java

@@ -1,5 +1,6 @@
 package org.hswebframework.web.authorization.basic.web;
 
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.authorization.token.UserToken;
 import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@@ -33,14 +34,8 @@ public class WebUserTokenInterceptor extends HandlerInterceptorAdapter {
         UserToken userToken = userTokenManager.getByToken(token);
         if (userToken == null) {
             return true;
-        } else if (userToken.isEffective()) {
+        } else {
             UserTokenHolder.setCurrent(userToken);
-        } else if (userToken.isExpired()) {
-            // TODO: 17-8-16 发送登录超时的错误信息
-            userTokenManager.signOutByToken(token);
-        } else if (userToken.isOffline()) {
-            // TODO: 17-8-16 发送已被踢出的错误信息
-            userTokenManager.signOutByToken(token);
         }
         return true;
     }

+ 1 - 34
hsweb-authorization/hsweb-authorization-shiro/README.md

@@ -1,36 +1,3 @@
 # shiro 权限控制实现
 
-[shiro官方文档](http://shiro.apache.org/documentation.html)
-
-本模块对shiro进行拓展,增加对[hsweb-authorization-api](../hsweb-authorization-api)中的注解进行实现。
-实现类如下:
-
-| 注解名称       | 实现类       | 
-| ------------- |:-------------:| 
-| [`@Authorize`](../hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/Authorize.java)    |      [ExpressionAnnotationMethodInterceptor](src/main/java/org/hswebframework/web/authorization/shiro/boost/SimpleAuthorizeMethodInterceptor.java)        |
-| [`@RequiresExpression`](../hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresExpression.java)    | [ExpressionAnnotationMethodInterceptor](src/main/java/org/hswebframework/web/authorization/shiro/boost/ExpressionAnnotationMethodInterceptor.java)      | 
-| [`@RequiresDataAccess`](../hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/annotation/RequiresDataAccess.java)    | [DataAccessAnnotationMethodInterceptor](src/main/java/org/hswebframework/web/authorization/shiro/boost/DataAccessAnnotationMethodInterceptor.java)      | 
-
-## 拓展接口
-
-### 数据级权限控制器
-
-控制逻辑简述:
-
-1. 获取被拦截方法的注解信息,取得当前需要验证的permission,action。如: user,query
-2. 根据上一步获取到需要验证的permission和action获取当前登录用户权限信息中配置的控制规则(控制规则可以在前端进行设置)
-3. 调用控制器进行验证
-
-可自己实现DataAccessHandler接口并注入spring以实现自定义的控制方式
-
-内置的控制方式
-
-1. [CustomDataAccessHandler](src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/CustomDataAccessHandler.java) 自定义控制器
-2. [OwnCreatedDataAccessHandler](src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/OwnCreatedDataAccessHandler.java) 控制只能操作自己创建的数据
-3. [ScriptDataAccessHandler](src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/ScriptDataAccessHandler.java) 使用脚本方式控制
-4. [FieldScopeDataAccessHandler](src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/FieldScopeDataAccessHandler.java) 控制字段的值范围,如: orgId in (1,2,3,4)
-5. [FieldFilterDataAccessHandler](src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/FieldFilterDataAccessHandler.java) 控制字段的操作范围,此控制器替代之前的FieldAccess功能
-
-
-注意: 控制需满足的条件请查看控制器源代码查看注释获取
-
+shiro实现已被砍,请看[basic实现](../hsweb-authorization-basic)

+ 0 - 27
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/ShiroAutoConfiguration.java

@@ -34,9 +34,7 @@ import org.hswebframework.web.authorization.AuthenticationHolder;
 import org.hswebframework.web.authorization.AuthenticationManager;
 import org.hswebframework.web.authorization.AuthenticationSupplier;
 import org.hswebframework.web.authorization.access.DataAccessController;
-import org.hswebframework.web.authorization.access.DataAccessHandler;
 import org.hswebframework.web.authorization.shiro.boost.BoostAuthorizationAttributeSourceAdvisor;
-import org.hswebframework.web.authorization.shiro.boost.DefaultDataAccessController;
 import org.hswebframework.web.authorization.shiro.cache.SpringCacheManagerWrapper;
 import org.hswebframework.web.authorization.shiro.remember.SimpleRememberMeManager;
 import org.hswebframework.web.controller.message.ResponseMessage;
@@ -145,31 +143,6 @@ public class ShiroAutoConfiguration {
         return securityManager;
     }
 
-    @Bean
-    @ConditionalOnMissingBean
-    public DefaultDataAccessController defaultDataAccessController() {
-        return new DefaultDataAccessController();
-    }
-
-    @Bean
-    @ConditionalOnBean(DefaultDataAccessController.class)
-    public BeanPostProcessor dataAccessControllerProcessor(DefaultDataAccessController defaultDataAccessController) {
-        return new BeanPostProcessor() {
-            @Override
-            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
-                return bean;
-            }
-
-            @Override
-            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
-                if (bean instanceof DataAccessHandler) {
-                    defaultDataAccessController.addHandler(((DataAccessHandler) bean));
-                }
-                return bean;
-            }
-        };
-    }
-
 
     @Bean
     public BoostAuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager,

+ 1 - 9
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/BoostAuthorizationAttributeSourceAdvisor.java

@@ -51,9 +51,7 @@ public class BoostAuthorizationAttributeSourceAdvisor extends StaticMethodMatche
                     RequiresGuest.class,
                     RequiresAuthentication.class,
                     //自定义
-                    RequiresExpression.class,
-                    Authorize.class,
-                    RequiresDataAccess.class
+                    Authorize.class
             };
 
     protected SecurityManager securityManager = null;
@@ -73,12 +71,6 @@ public class BoostAuthorizationAttributeSourceAdvisor extends StaticMethodMatche
                     }
                 };
         AnnotationResolver resolver = new SpringAnnotationResolver();
-        // @RequiresExpression support
-        interceptor.getMethodInterceptors().add(new ExpressionAnnotationMethodInterceptor(resolver));
-        // @RequiresDataAccess support
-        interceptor.getMethodInterceptors().add(new DataAccessAnnotationMethodInterceptor(dataAccessController, resolver));
-        // @Authorize support
-        interceptor.getMethodInterceptors().add(new SimpleAuthorizeMethodInterceptor(resolver));
         setAdvice(interceptor);
     }
 

+ 0 - 150
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DataAccessAnnotationMethodInterceptor.java

@@ -1,150 +0,0 @@
-/*
- * Copyright 2016 http://www.hswebframework.org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.hswebframework.web.authorization.shiro.boost;
-
-import org.apache.shiro.aop.AnnotationResolver;
-import org.apache.shiro.authc.AuthenticationException;
-import org.apache.shiro.authz.AuthorizationException;
-import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
-import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;
-import org.hswebframework.web.ApplicationContextHolder;
-import org.hswebframework.web.AuthorizeException;
-import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.Permission;
-import org.hswebframework.web.authorization.access.DataAccessConfig;
-import org.hswebframework.web.authorization.access.DataAccessController;
-import org.hswebframework.web.authorization.annotation.Authorize;
-import org.hswebframework.web.authorization.annotation.Logical;
-import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-import org.hswebframework.utils.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.annotation.Annotation;
-import java.util.*;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-/**
- * 数据级权限控制实现 <br>
- * 通过在方法上注解{@link RequiresDataAccess},标识需要进行数据级权限控制<br>
- * 控制的方式和规则由 {@link Permission#getDataAccesses()}实现<br>
- *
- * @author zhouhao
- * @see DefaultDataAccessController
- * @see DataAccessAnnotationHandler#assertAuthorized(Annotation)
- * @since 3.0
- */
-public class DataAccessAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
-
-    public DataAccessAnnotationMethodInterceptor(DataAccessController controller, AnnotationResolver resolver) {
-        super(new DataAccessAnnotationHandler(controller), resolver);
-    }
-
-    private static final Logger logger = LoggerFactory.getLogger(DataAccessAnnotationMethodInterceptor.class);
-
-    static class DataAccessAnnotationHandler extends AuthorizingAnnotationHandler {
-        protected DataAccessController dataAccessController;
-
-        public DataAccessAnnotationHandler(DataAccessController controller) {
-            super(RequiresDataAccess.class);
-            this.dataAccessController = controller;
-        }
-
-        final Map<Class<DataAccessController>, DataAccessController> cache = new HashMap<>(128);
-
-        @Override
-        public void assertAuthorized(Annotation a) throws AuthorizationException {
-            if (!(a instanceof RequiresDataAccess)) return;
-            MethodInterceptorHolder holder = MethodInterceptorHolder.current();
-            if (null == holder) {
-                logger.warn("MethodInterceptorHolder is null!");
-                return;
-            }
-            //无权限信息
-            Authentication authentication = Authentication.current().orElseThrow(AuthorizeException::new);
-            RequiresDataAccess accessAnn = ((RequiresDataAccess) a);
-            DataAccessController accessController = dataAccessController;
-            //在注解上自定义的权限控制器
-            if (DataAccessController.class != accessAnn.controllerClass()) {
-                if (null == (accessController = cache.get(accessAnn.controllerClass()))) {
-                    synchronized (cache) {
-                        if (null == (accessController = cache.get(accessAnn.controllerClass())))
-                            try {
-                                accessController = accessAnn.controllerClass().newInstance();
-                                cache.put(accessAnn.controllerClass(), accessController);
-                            } catch (Exception e) {
-                                throw new RuntimeException(e);
-                            }
-                    }
-                }
-            } else if (!StringUtils.isNullOrEmpty(accessAnn.controllerBeanName())) {
-                //获取spring上下文中的控制器
-                accessController = ApplicationContextHolder.get().getBean(accessAnn.controllerBeanName(), DataAccessController.class);
-            }
-            DataAccessController finalAccessController = accessController;
-            Authorize classAnnotation = holder.findClassAnnotation(Authorize.class);
-            Authorize methodAnnotation = holder.findMethodAnnotation(Authorize.class);
-            Set<String> permissions = new HashSet<>();
-            List<String> actionList = new ArrayList<>(Arrays.asList(accessAnn.action()));
-
-            if (classAnnotation != null) {
-                permissions.addAll(Arrays.asList(classAnnotation.permission()));
-                if (actionList.isEmpty())
-                    actionList.addAll(Arrays.asList(classAnnotation.action()));
-            }
-            if (methodAnnotation != null) {
-                permissions.addAll(Arrays.asList(methodAnnotation.permission()));
-                if (actionList.isEmpty())
-                    actionList.addAll(Arrays.asList(methodAnnotation.action()));
-            }
-
-            String permission = accessAnn.permission();
-
-            if ("".equals(permission)) {
-                if (permissions.size() != 1) {
-                    throw new IndexOutOfBoundsException("permission setting size must be 1");
-                }
-                permission = permissions.iterator().next();
-            }
-            MethodInterceptorParamContext context = holder.createParamContext();
-            Permission permissionInfo = authentication.getPermission(permission).orElseThrow(AuthenticationException::new);
-
-            //取得当前登录用户持有的控制规则
-            Set<DataAccessConfig> accesses = permissionInfo
-                    .getDataAccesses()
-                    .stream()
-                    .filter(access -> actionList.contains(access.getAction()))
-                    .collect(Collectors.toSet());
-            //无规则,则代表不进行控制
-            if (accesses.isEmpty()) return;
-            //单个规则验证函数
-            Function<Predicate<DataAccessConfig>, Boolean> function =
-                    accessAnn.logical() == Logical.AND ?
-                            accesses.stream()::allMatch : accesses.stream()::anyMatch;
-            //调用控制器进行验证
-            boolean isAccess = function.apply(access -> finalAccessController.doAccess(access, context));
-            if (!isAccess) {
-                throw new AuthorizationException("{access_deny}");
-            }
-        }
-    }
-}

+ 0 - 60
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/DefaultDataAccessController.java

@@ -1,60 +0,0 @@
-package org.hswebframework.web.authorization.shiro.boost;
-
-import org.hswebframework.web.authorization.access.DataAccessConfig;
-import org.hswebframework.web.authorization.access.DataAccessController;
-import org.hswebframework.web.authorization.access.DataAccessHandler;
-import org.hswebframework.web.authorization.shiro.boost.handler.*;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * 默认的行级权限控制.通过获取DataAccessHandler进行实际处理
- *
- * @author zhouhao
- * @see DataAccessHandler
- * @since 3.0
- */
-public final class DefaultDataAccessController implements DataAccessController {
-
-    private DataAccessController parent;
-
-    private List<DataAccessHandler> handlers = new LinkedList<>();
-
-    public DefaultDataAccessController() {
-        this(null);
-    }
-
-    public DefaultDataAccessController(DataAccessController parent) {
-        if (parent == this) throw new UnsupportedOperationException();
-        this.parent = parent;
-        addHandler(new CustomDataAccessHandler());
-        addHandler(new OwnCreatedDataAccessHandler());
-        addHandler(new ScriptDataAccessHandler());
-        addHandler(new FieldFilterDataAccessHandler());
-        addHandler(new FieldScopeDataAccessHandler());
-    }
-
-    @Override
-    public boolean doAccess(DataAccessConfig access, MethodInterceptorParamContext params) {
-        if (parent != null) parent.doAccess(access, params);
-        return handlers.parallelStream()
-                // TODO: 17-3-28 可以换成access对应的handler以提高效率
-                .filter(handler -> handler.isSupport(access))
-                .allMatch(handler -> handler.handle(access, params));
-    }
-
-    public DefaultDataAccessController addHandler(DataAccessHandler handler) {
-        handlers.add(handler);
-        return this;
-    }
-
-    public void setHandlers(List<DataAccessHandler> handlers) {
-        this.handlers = handlers;
-    }
-
-    public List<DataAccessHandler> getHandlers() {
-        return handlers;
-    }
-}

+ 0 - 87
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/ExpressionAnnotationMethodInterceptor.java

@@ -1,87 +0,0 @@
-/*
- * Copyright 2016 http://www.hswebframework.org
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *       http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.hswebframework.web.authorization.shiro.boost;
-
-import org.apache.shiro.aop.AnnotationResolver;
-import org.apache.shiro.authz.AuthorizationException;
-import org.apache.shiro.authz.aop.AuthorizingAnnotationHandler;
-import org.apache.shiro.authz.aop.AuthorizingAnnotationMethodInterceptor;
-import org.hswebframework.expands.script.engine.DynamicScriptEngine;
-import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
-import org.hswebframework.web.BusinessException;
-import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.annotation.RequiresExpression;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.lang.annotation.Annotation;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public class ExpressionAnnotationMethodInterceptor extends AuthorizingAnnotationMethodInterceptor {
-    public ExpressionAnnotationMethodInterceptor() {
-        super(new ExpressionAnnotationHandler());
-    }
-
-    public ExpressionAnnotationMethodInterceptor(AnnotationResolver resolver) {
-        super(new ExpressionAnnotationHandler(), resolver);
-    }
-
-    private static final Logger logger = LoggerFactory.getLogger(ExpressionAnnotationMethodInterceptor.class);
-
-    static class ExpressionAnnotationHandler extends AuthorizingAnnotationHandler {
-
-        public ExpressionAnnotationHandler() {
-            super(RequiresExpression.class);
-        }
-
-        @Override
-        public void assertAuthorized(Annotation a) throws AuthorizationException {
-            if (!(a instanceof RequiresExpression)) return;
-            MethodInterceptorHolder holder = MethodInterceptorHolder.current();
-            if (null == holder) {
-                return;
-            }
-            RequiresExpression expression = ((RequiresExpression) a);
-            DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(expression.language());
-            if (null == engine) {
-                throw new AuthorizationException("{unknown_engine}:" + expression.language());
-            }
-            if (!engine.compiled(holder.getId())) {
-                try {
-                    engine.compile(holder.getId(), expression.value());
-                } catch (Exception e) {
-                    logger.error("express compile error", e);
-                    throw new BusinessException("{expression_error}");
-                }
-            }
-            Map<String, Object> var = new HashMap<>(holder.getArgs());
-            var.put("auth", getSubject().getSession().getAttribute(Authentication.class.getName()));
-            Object success = engine.execute(holder.getId(), var).get();
-            if (!(success instanceof Boolean) || !((Boolean) success)) {
-                throw new AuthorizationException();
-            }
-        }
-    }
-}

+ 0 - 42
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/CustomDataAccessHandler.java

@@ -1,42 +0,0 @@
-/*
- *  Copyright 2016 http://www.hswebframework.org
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- *
- */
-
-package org.hswebframework.web.authorization.shiro.boost.handler;
-
-import org.hswebframework.web.authorization.access.*;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-
-/**
- * 当配置为自定义处理器时(实现{@link CustomDataAccessConfig }接口),此处理器生效
- *
- * @author zhouhao
- * @see 3.0
- */
-public class CustomDataAccessHandler implements DataAccessHandler {
-
-    @Override
-    public boolean isSupport(DataAccessConfig access) {
-        return access instanceof CustomDataAccessConfig;
-    }
-
-    @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
-        CustomDataAccessConfig custom = ((CustomDataAccessConfig) access);
-        return custom.getController().doAccess(access, context);
-    }
-}

+ 0 - 86
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/FieldFilterDataAccessHandler.java

@@ -1,86 +0,0 @@
-package org.hswebframework.web.authorization.shiro.boost.handler;
-
-import org.apache.commons.beanutils.BeanUtilsBean;
-import org.hswebframework.web.authorization.Permission;
-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.boost.aop.context.MethodInterceptorParamContext;
-import org.hswebframework.web.commons.entity.Entity;
-import org.hswebframework.web.commons.entity.param.QueryParamEntity;
-import org.hswebframework.web.commons.model.Model;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * 数据权限字段过滤处理,目前仅支持deny. {@link DataAccessConfig.DefaultType#DENY_FIELDS}
- *
- * @author zhouhao
- */
-public class FieldFilterDataAccessHandler implements DataAccessHandler {
-    private Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    @Override
-    public boolean isSupport(DataAccessConfig access) {
-        return access instanceof FieldFilterDataAccessConfig && DataAccessConfig.DefaultType.DENY_FIELDS.equals(access.getType());
-    }
-
-    @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
-        FieldFilterDataAccessConfig filterDataAccessConfig = ((FieldFilterDataAccessConfig) access);
-
-        switch (access.getAction()) {
-            case Permission.ACTION_QUERY:
-                return doQueryAccess(filterDataAccessConfig, context);
-            case Permission.ACTION_UPDATE:
-                return doUpdateAccess(filterDataAccessConfig, context);
-            default:
-                if (logger.isDebugEnabled())
-                    logger.debug("field filter not support for {}", access.getAction());
-                return true;
-        }
-    }
-
-    /**
-     * @param accesses 不可操作的字段
-     * @param params   参数上下文
-     * @return true
-     * @see BeanUtilsBean
-     * @see org.apache.commons.beanutils.PropertyUtilsBean
-     */
-    protected boolean doUpdateAccess(FieldFilterDataAccessConfig accesses, MethodInterceptorParamContext params) {
-        Object supportParam = params.getParams().values().stream()
-                .filter(param -> (param instanceof Entity) | (param instanceof Model))
-                .findAny().orElse(null);
-        if (null != supportParam) {
-            for (String field : accesses.getFields()) {
-                try {
-                    //设置值为null,跳过修改
-                    BeanUtilsBean.getInstance()
-                            .getPropertyUtils()
-                            .setProperty(supportParam, field, null);
-                } catch (Exception e) {
-                    logger.warn("can't set {} null", field, e);
-                }
-            }
-        } else {
-            logger.warn("doUpdateAccess skip ,because can not found any entity in param!");
-        }
-        return true;
-    }
-
-
-    protected boolean doQueryAccess(FieldFilterDataAccessConfig access, MethodInterceptorParamContext context) {
-        QueryParamEntity entity = context.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()]));
-        return true;
-    }
-}

+ 0 - 114
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/FieldScopeDataAccessHandler.java

@@ -1,114 +0,0 @@
-package org.hswebframework.web.authorization.shiro.boost.handler;
-
-import org.apache.commons.beanutils.BeanUtilsBean;
-import org.apache.commons.beanutils.PropertyUtilsBean;
-import org.hsweb.ezorm.core.param.Term;
-import org.hsweb.ezorm.core.param.TermType;
-import org.hswebframework.web.authorization.Permission;
-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.annotation.RequiresDataAccess;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-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.util.ArrayList;
-import java.util.List;
-
-/**
- * @author zhouhao
- */
-public class FieldScopeDataAccessHandler implements DataAccessHandler {
-    private PropertyUtilsBean propertyUtilsBean = BeanUtilsBean.getInstance().getPropertyUtils();
-
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
-    @Override
-    public boolean isSupport(DataAccessConfig access) {
-        return access instanceof FieldScopeDataAccessConfig;
-    }
-
-    @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
-        FieldScopeDataAccessConfig own = ((FieldScopeDataAccessConfig) access);
-        Object controller = context.getTarget();
-        if (controller != null) {
-            switch (access.getAction()) {
-                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);
-                case Permission.ACTION_ADD:
-                default:
-                    logger.warn("action: {} not support now!", access.getAction());
-            }
-        } else {
-            logger.warn("target is null!");
-        }
-        return true;
-    }
-
-    @SuppressWarnings("unchecked")
-    protected boolean doRWAccess(FieldScopeDataAccessConfig access, MethodInterceptorParamContext context, Object controller) {
-        //获取注解
-        RequiresDataAccess dataAccess = context.getAnnotation(RequiresDataAccess.class);
-        Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
-        //通过QueryController获取QueryService
-        //然后调用selectByPk 查询旧的数据,进行对比
-        if (controller instanceof QueryController) {
-            QueryService queryService = (QueryService) ((QueryController) controller).getService();
-            Object oldData = queryService.selectByPk(id);
-            if (oldData != null) {
-                try {
-                    Object value = propertyUtilsBean.getProperty(oldData, access.getField());
-                    return access.getScope().contains(value);
-                } catch (Exception e) {
-                    logger.error("can't read property {}", access.getField(), e);
-                }
-                return false;
-            }
-        } else {
-            logger.warn("controller is not instanceof QueryController");
-        }
-        return true;
-    }
-
-
-    protected boolean doQueryAccess(FieldScopeDataAccessConfig access, MethodInterceptorParamContext context) {
-        QueryParamEntity entity = context.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);
-        return true;
-    }
-
-    protected Term createQueryTerm(FieldScopeDataAccessConfig access) {
-        Term term = new Term();
-        term.setType(Term.Type.and);
-        term.setColumn(access.getField());
-        term.setTermType(TermType.in);
-        term.setValue(access.getScope());
-        return term;
-    }
-}

+ 0 - 129
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/OwnCreatedDataAccessHandler.java

@@ -1,129 +0,0 @@
-package org.hswebframework.web.authorization.shiro.boost.handler;
-
-import org.hsweb.ezorm.core.param.Term;
-import org.hswebframework.web.AuthorizeException;
-import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.Permission;
-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.annotation.RequiresDataAccess;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-import org.hswebframework.web.commons.entity.Entity;
-import org.hswebframework.web.commons.entity.RecordCreationEntity;
-import org.hswebframework.web.commons.entity.param.QueryParamEntity;
-import org.hswebframework.web.controller.QueryController;
-import org.hswebframework.web.service.QueryService;
-import org.hswebframework.utils.ClassUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public class OwnCreatedDataAccessHandler implements DataAccessHandler {
-    private static final Logger logger = LoggerFactory.getLogger(OwnCreatedDataAccessHandler.class);
-
-    @Override
-    public boolean isSupport(DataAccessConfig access) {
-        return access instanceof OwnCreatedDataAccessConfig;
-    }
-
-    @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
-        OwnCreatedDataAccessConfig own = ((OwnCreatedDataAccessConfig) access);
-        Object controller = context.getTarget();
-        if (controller != null) {
-            switch (access.getAction()) {
-                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);
-                case Permission.ACTION_ADD:
-                    //put creator_id to data
-                    return putCreatorId(own, context);
-                default:
-                    logger.warn("action: {} not support now!", access.getAction());
-            }
-        } else {
-            logger.warn("target is null!");
-        }
-        return true;
-    }
-
-    public boolean putCreatorId(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context) {
-        RecordCreationEntity entity = context.getParams()
-                .values().stream()
-                .filter(RecordCreationEntity.class::isInstance)
-                .map(RecordCreationEntity.class::cast)
-                .findAny().orElse(null);
-        if (entity != null) {
-            entity.setCreatorId(Authentication.current()
-                    .orElseThrow(AuthorizeException::new)
-                    .getUser().getId());
-        } else {
-            logger.warn("try put creatorId property,but not found any RecordCreationEntity!");
-        }
-        return true;
-    }
-
-    @SuppressWarnings("unchecked")
-    protected boolean doRWAccess(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context, Object controller) {
-        //获取注解
-        RequiresDataAccess dataAccess = context.getAnnotation(RequiresDataAccess.class);
-        Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
-        //通过QueryController获取QueryService
-        //然后调用selectByPk 查询旧的数据,进行对比
-        if (controller instanceof QueryController) {
-            //判断是否满足条件(泛型为 RecordCreationEntity)
-            Class entityType = ClassUtils.getGenericType(controller.getClass(), 0);
-            if (ClassUtils.instanceOf(entityType, RecordCreationEntity.class)) {
-                QueryService<RecordCreationEntity, Object> queryService =
-                        ((QueryController<RecordCreationEntity, Object, Entity>) controller).getService();
-                RecordCreationEntity oldData = queryService.selectByPk(id);
-                if (oldData != null && !Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId().equals(oldData.getCreatorId())) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    protected boolean doQueryAccess(OwnCreatedDataAccessConfig access, MethodInterceptorParamContext context) {
-        Entity entity = context.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, Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId())
-                    //客户端提交的参数 作为嵌套参数
-                    .nest().setTerms(oldParam);
-        } else if (entity instanceof RecordCreationEntity) {
-            ((RecordCreationEntity) entity).setCreatorId(Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId());
-        } else {
-            logger.warn("try validate query access,but entity not support, QueryParamEntity and RecordCreationEntity support now!");
-        }
-        return true;
-    }
-}

+ 0 - 39
hsweb-authorization/hsweb-authorization-shiro/src/main/java/org/hswebframework/web/authorization/shiro/boost/handler/ScriptDataAccessHandler.java

@@ -1,39 +0,0 @@
-package org.hswebframework.web.authorization.shiro.boost.handler;
-
-import org.apache.commons.codec.digest.DigestUtils;
-import org.hswebframework.expands.script.engine.DynamicScriptEngine;
-import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
-import org.hswebframework.web.BusinessException;
-import org.hswebframework.web.authorization.access.*;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-import org.hswebframework.utils.StringUtils;
-
-/**
- * TODO 完成注释
- *
- * @author zhouhao
- */
-public class ScriptDataAccessHandler implements DataAccessHandler {
-    @Override
-    public boolean isSupport(DataAccessConfig access) {
-        return access instanceof ScriptDataAccessConfig;
-    }
-
-    @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
-        ScriptDataAccessConfig dataAccess = ((ScriptDataAccessConfig) access);
-        DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(dataAccess.getScriptLanguage());
-        if (engine == null) throw new UnsupportedOperationException(dataAccess.getScriptLanguage() + " {not_support}");
-        String scriptId = DigestUtils.md5Hex(dataAccess.getScript());
-        try {
-            if (!engine.compiled(scriptId)) {
-                engine.compile(scriptId, dataAccess.getScript());
-            }
-            Object success = engine.execute(scriptId, context.getParams()).getIfSuccess();
-            return StringUtils.isTrue(success);
-        } catch (Exception e) {
-            throw new BusinessException("{script_error}", e);
-        }
-    }
-
-}

+ 1 - 1
hsweb-boost/hsweb-boost-aop/src/main/java/org/hswebframework/web/boost/aop/context/MethodInterceptorParamContext.java

@@ -30,7 +30,7 @@ import java.util.Optional;
  * @author zhouhao
  * @see 3.0
  */
-public interface MethodInterceptorParamContext extends Serializable {
+public interface MethodInterceptorContext extends Serializable {
 
     /**
      * 获取当前类实例

+ 2 - 2
hsweb-boost/hsweb-boost-aop/src/main/java/org/hswebframework/web/boost/aop/context/MethodInterceptorHolder.java

@@ -119,8 +119,8 @@ public class MethodInterceptorHolder {
         return AopUtils.findAnnotation(target.getClass(), method, annClass);
     }
 
-    public MethodInterceptorParamContext createParamContext() {
-        return new MethodInterceptorParamContext() {
+    public MethodInterceptorContext createParamContext() {
+        return new MethodInterceptorContext() {
             @Override
             public Object getTarget() {
                 return target;

+ 2 - 2
hsweb-boost/hsweb-boost-validator/hsweb-boost-validator-api/src/main/java/org/hswebframework/web/boost/validator/DuplicateValidator.java

@@ -18,7 +18,7 @@
 
 package org.hswebframework.web.boost.validator;
 
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorContext;
 
 /**
  * 重复数据验证器,验证数据是否重复
@@ -26,7 +26,7 @@ import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
  * @author zhouhao
  */
 public interface DuplicateValidator {
-    Result doValidate(DuplicateValidatorConfig validator, MethodInterceptorParamContext context);
+    Result doValidate(DuplicateValidatorConfig validator, MethodInterceptorContext context);
 
     /**
      * 验证结果

+ 4 - 4
hsweb-commons/hsweb-commons-controller/src/main/java/org/hswebframework/web/controller/message/ResponseMessage.java

@@ -82,9 +82,9 @@ public class ResponseMessage<T> implements Serializable {
         return this;
     }
 
-    public static <T> ResponseMessage<T> ok(T data) {
+    public static <T> ResponseMessage<T> ok(T result) {
         return new ResponseMessage<T>()
-                .data(data)
+                .result(result)
                 .putTimeStamp()
                 .status(200);
     }
@@ -94,8 +94,8 @@ public class ResponseMessage<T> implements Serializable {
 //        return this;
 //    }
 
-    public ResponseMessage<T> data(T data) {
-        this.result = data;
+    public ResponseMessage<T> result(T result) {
+        this.result = result;
         return this;
     }
 

+ 16 - 0
hsweb-commons/hsweb-commons-service/hsweb-commons-service-simple/src/main/java/org/hswebframework/web/service/AbstractTreeSortService.java

@@ -17,9 +17,11 @@
 
 package org.hswebframework.web.service;
 
+import org.hswebframework.utils.RandomUtil;
 import org.hswebframework.web.commons.entity.TreeSortSupportEntity;
 import org.hswebframework.web.commons.entity.TreeSupportEntity;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -52,9 +54,22 @@ public abstract class AbstractTreeSortService<E extends TreeSortSupportEntity<PK
         return createQuery().where(TreeSupportEntity.parentId, parentId).noPaging().list();
     }
 
+    protected void applyPath(E entity) {
+        if (!StringUtils.isEmpty(entity.getParentId())) return;
+        if (!StringUtils.isEmpty(entity.getPath())) return;
+
+        TreeSortSupportEntity<PK> parent = selectByPk(entity.getParentId());
+        if (null == parent) {
+            entity.setParentId(null);
+        } else {
+            entity.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4));
+        }
+    }
+
     @Override
     public PK insert(E entity) {
         if (entity.getId() == null) entity.setId(getIDGenerator().generate());
+        applyPath(entity);
         List<E> childrenList = new ArrayList<>();
         TreeSupportEntity.expandTree2List(entity, childrenList, getIDGenerator());
         super.insert(entity);
@@ -87,6 +102,7 @@ public abstract class AbstractTreeSortService<E extends TreeSortSupportEntity<PK
     public PK saveOrUpdateForSingle(E entity) {
         assertNotNull(entity);
         PK id = entity.getId();
+        applyPath(entity);
         if (null == id || this.selectByPk(id) == null) {
             if (null == id)
                 entity.setId(getIDGenerator().generate());

+ 0 - 39
hsweb-core/src/main/java/org/hswebframework/web/AuthorizeException.java

@@ -1,39 +0,0 @@
-/*
- *
- *  * Copyright 2016 http://www.hswebframework.org
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *     http://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package org.hswebframework.web;
-
-public class AuthorizeException extends BusinessException {
-    private static final long serialVersionUID = 2422918455013900645L;
-
-    public AuthorizeException() {
-        this("{no_authorization}");
-    }
-
-    public AuthorizeException(String message) {
-        this(message, 401);
-    }
-
-    public AuthorizeException(String message, int status) {
-        super(message, status);
-    }
-
-    public AuthorizeException(String message, Throwable cause, int status) {
-        super(message, cause, status);
-    }
-}

+ 0 - 38
hsweb-core/src/main/java/org/hswebframework/web/AuthorizeForbiddenException.java

@@ -1,38 +0,0 @@
-/*
- *
- *  * Copyright 2016 http://www.hswebframework.org
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *     http://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package org.hswebframework.web;
-
-/**
- * Created by 浩 on 2015-12-23 0023.
- */
-public class AuthorizeForbiddenException extends BusinessException {
-    private static final long serialVersionUID = 2422918455013900645L;
-
-    public AuthorizeForbiddenException(String message) {
-        this(message, 403);
-    }
-
-    public AuthorizeForbiddenException(String message, int status) {
-        super(message, status);
-    }
-
-    public AuthorizeForbiddenException(String message, Throwable cause, int status) {
-        super(message, cause, status);
-    }
-}

+ 14 - 5
hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java

@@ -18,10 +18,12 @@
 package org.hswebframework.web.example.simple;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.basic.configuration.EnableAopAuthorize;
+import org.hswebframework.web.authorization.basic.web.UserTokenHolder;
 import org.hswebframework.web.authorization.simple.SimpleFieldFilterDataAccessConfig;
 import org.hswebframework.web.commons.entity.DataStatus;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
@@ -64,6 +66,7 @@ import java.io.OutputStream;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.stream.Stream;
 
 /**
@@ -91,11 +94,17 @@ public class SpringBootExample
                 MultipartFile.class,
                 MultipartFile[].class
         };
-        return loggerInfo -> System.out.println("有请求啦:" + JSON.toJSONString(loggerInfo.toSimpleMap(obj -> {
-            if (Stream.of(excludes).anyMatch(aClass -> aClass.isInstance(obj)))
-                return obj.getClass().getName();
-            return JSON.toJSONString(obj);
-        })));
+        return loggerInfo -> {
+            Map<String, Object> loggerMap = loggerInfo.toSimpleMap(obj -> {
+                if (Stream.of(excludes).anyMatch(aClass -> aClass.isInstance(obj)))
+                    return obj.getClass().getName();
+                return JSON.toJSONString(obj);
+            });
+            loggerMap.put("userToken", UserTokenHolder.currentToken());
+
+            System.out.println(JSON.toJSONString(loggerMap, SerializerFeature.SortField, SerializerFeature.PrettyFormat));
+
+        };
     }
 
     @Bean

+ 2 - 2
hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/TestController.java

@@ -1,11 +1,11 @@
 package org.hswebframework.web.example.simple;
 
 import io.swagger.annotations.ApiOperation;
-import org.hswebframework.web.AuthorizeException;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.PagerResult;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
@@ -94,7 +94,7 @@ public class TestController implements QueryController<UserEntity, String, Query
         public UserEntity selectByPk(String id) {
             SimpleUserEntity userEntity = new SimpleUserEntity();
             // 同一个用户
-            userEntity.setCreatorId(Authentication.current().orElseThrow(AuthorizeException::new).getUser().getId());
+            userEntity.setCreatorId(Authentication.current().orElseThrow(UnAuthorizedException::new).getUser().getId());
             return userEntity;
         }
 

+ 6 - 10
hsweb-logging/hsweb-access-logging-api/src/main/java/org/hswebframework/web/logging/AccessLoggerInfo.java

@@ -4,7 +4,6 @@ import java.io.PrintWriter;
 import java.io.Serializable;
 import java.io.StringWriter;
 import java.lang.reflect.Method;
-import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.StringJoiner;
@@ -198,7 +197,10 @@ public class AccessLoggerInfo {
     }
 
     public Map<String, Object> toSimpleMap(Function<Object, Serializable> noSerialExchange) {
-        Map<String, Object> map = new HashMap<>(16);
+        return toSimpleMap(noSerialExchange, new LinkedHashMap<>());
+    }
+
+    public Map<String, Object> toSimpleMap(Function<Object, Serializable> objectFilter, Map<String, Object> map) {
         map.put("action", action);
         map.put("describe", describe);
         if (method != null) {
@@ -215,7 +217,7 @@ public class AccessLoggerInfo {
         Map<String, Object> newParameter = new LinkedHashMap<>(parameters);
         newParameter.entrySet().forEach(entry -> {
             if (entry.getValue() != null) {
-                entry.setValue(noSerialExchange.apply(entry.getValue()));
+                entry.setValue(objectFilter.apply(entry.getValue()));
             }
         });
 
@@ -224,11 +226,7 @@ public class AccessLoggerInfo {
         map.put("httpMethod", httpMethod);
         map.put("ip", ip);
         map.put("url", url);
-        if (response instanceof Serializable) {
-            map.put("response", response);
-        } else {
-            map.put("response", noSerialExchange.apply(response));
-        }
+        map.put("response", objectFilter.apply(response));
         map.put("requestTime", requestTime);
         map.put("responseTime", responseTime);
         map.put("useTime", responseTime - requestTime);
@@ -237,8 +235,6 @@ public class AccessLoggerInfo {
             exception.printStackTrace(new PrintWriter(writer));
             map.put("exception", writer.toString());
         }
-
-
         return map;
     }
 }

+ 11 - 15
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/RestControllerExceptionTranslator.java

@@ -18,10 +18,10 @@
 package org.hswebframework.web.starter;
 
 import com.alibaba.fastjson.JSONException;
-import org.hswebframework.web.AuthorizeException;
-import org.hswebframework.web.AuthorizeForbiddenException;
 import org.hswebframework.web.BusinessException;
 import org.hswebframework.web.NotFoundException;
+import org.hswebframework.web.authorization.exception.AccessDenyException;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframework.web.validate.SimpleValidateResults;
 import org.hswebframework.web.validate.ValidateResults;
@@ -29,10 +29,7 @@ import org.hswebframework.web.validate.ValidationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpStatus;
-import org.springframework.validation.BindingResult;
-import org.springframework.validation.BindingResultUtils;
 import org.springframework.validation.FieldError;
-import org.springframework.validation.ObjectError;
 import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ResponseBody;
@@ -58,7 +55,7 @@ public class RestControllerExceptionTranslator {
     @ResponseStatus(HttpStatus.BAD_REQUEST)
     @ResponseBody
     ResponseMessage<Object> handleException(org.hsweb.ezorm.rdb.exception.ValidationException exception) {
-        return ResponseMessage.error(400, exception.getMessage()).data(exception.getValidateResult());
+        return ResponseMessage.error(400, exception.getMessage()).result(exception.getValidateResult());
     }
 
     @ExceptionHandler(ValidationException.class)
@@ -66,7 +63,7 @@ public class RestControllerExceptionTranslator {
     @ResponseBody
     ResponseMessage<List<ValidateResults.Result>> handleException(ValidationException exception) {
         return ResponseMessage.<List<ValidateResults.Result>>error(400, exception.getMessage())
-                .data(exception.getResults());
+                .result(exception.getResults());
     }
 
     @ExceptionHandler(BusinessException.class)
@@ -79,21 +76,20 @@ public class RestControllerExceptionTranslator {
         return ResponseMessage.error(exception.getStatus(), exception.getMessage());
     }
 
-    @ExceptionHandler(AuthorizeException.class)
+    @ExceptionHandler(UnAuthorizedException.class)
     @ResponseStatus(HttpStatus.UNAUTHORIZED)
     @ResponseBody
-    ResponseMessage handleException(AuthorizeException exception) {
-        return ResponseMessage.error(exception.getStatus(), exception.getMessage());
+    ResponseMessage handleException(UnAuthorizedException exception) {
+        return ResponseMessage.error(401, exception.getMessage()).result(exception.getState());
     }
 
-    @ExceptionHandler(AuthorizeForbiddenException.class)
+    @ExceptionHandler(AccessDenyException.class)
     @ResponseStatus(HttpStatus.FORBIDDEN)
     @ResponseBody
-    ResponseMessage handleException(AuthorizeForbiddenException exception) {
-        return ResponseMessage.error(exception.getStatus(), exception.getMessage());
+    ResponseMessage handleException(AccessDenyException exception) {
+        return ResponseMessage.error(403, exception.getMessage());
     }
 
-
     @ExceptionHandler(NotFoundException.class)
     @ResponseStatus(HttpStatus.NOT_FOUND)
     @ResponseBody
@@ -112,7 +108,7 @@ public class RestControllerExceptionTranslator {
                 .map(FieldError.class::cast)
                 .forEach(fieldError -> results.addResult(fieldError.getField(), fieldError.getDefaultMessage()));
 
-        return ResponseMessage.error(400, results.getResults().size() == 0 ? e.getMessage() : results.getResults().get(0).getMessage()).data(results.getResults());
+        return ResponseMessage.error(400, results.getResults().size() == 0 ? e.getMessage() : results.getResults().get(0).getMessage()).result(results.getResults());
     }
 //    @ExceptionHandler(Throwable.class)
 //    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)

+ 2 - 4
hsweb-starter/hsweb-spring-boot-starter/src/main/java/org/hswebframework/web/starter/resolver/AuthorizationArgumentResolver.java

@@ -17,11 +17,9 @@
 
 package org.hswebframework.web.starter.resolver;
 
-import org.hswebframework.web.AuthorizeException;
 import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.AuthenticationSupplier;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.springframework.core.MethodParameter;
-import org.springframework.util.Assert;
 import org.springframework.web.bind.support.WebDataBinderFactory;
 import org.springframework.web.context.request.NativeWebRequest;
 import org.springframework.web.method.support.HandlerMethodArgumentResolver;
@@ -51,6 +49,6 @@ public class AuthorizationArgumentResolver implements HandlerMethodArgumentResol
 
     @Override
     public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
-        return Authentication.current().orElseThrow(AuthorizeException::new);
+        return Authentication.current().orElseThrow(UnAuthorizedException::new);
     }
 }

+ 3 - 6
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/AuthorizationController.java

@@ -23,7 +23,6 @@ import io.swagger.annotations.ApiParam;
 import org.hswebframework.web.BusinessException;
 import org.hswebframework.web.NotFoundException;
 import org.hswebframework.web.authorization.Authentication;
-//import org.hswebframework.web.authorization.AuthenticationInitializeService;
 import org.hswebframework.web.authorization.AuthenticationManager;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.listener.AuthorizationListenerDispatcher;
@@ -58,15 +57,13 @@ public class AuthorizationController {
     @Autowired
     private UserService userService;
 
-//    @Autowired
-//    private AuthenticationInitializeService authenticationInitializeService;
-
     @Autowired
-    private AuthenticationManager           authenticationManager;
+    private AuthenticationManager authenticationManager;
+
     @Autowired
     private AuthorizationListenerDispatcher authorizationListenerDispatcher;
 
-    @GetMapping("/login-out")
+    @GetMapping({"/login-out", "/sign-out", "/exit"})
     @Authorize
     @ApiOperation("退出当前登录")
     public ResponseMessage exit(@ApiParam(hidden = true) Authentication authentication) {

+ 33 - 4
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-controller/src/main/java/org/hswebframework/web/controller/authorization/UserController.java

@@ -19,10 +19,13 @@ package org.hswebframework.web.controller.authorization;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.hswebframework.web.AuthorizeException;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
+import org.hswebframework.web.authorization.token.TokenState;
+import org.hswebframework.web.authorization.token.UserToken;
+import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.hswebframework.web.commons.entity.PagerResult;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.CreateController;
@@ -31,16 +34,17 @@ import org.hswebframework.web.controller.message.ResponseMessage;
 import org.hswebframework.web.entity.authorization.UserEntity;
 import org.hswebframework.web.entity.authorization.bind.BindRoleUserEntity;
 import org.hswebframework.web.logging.AccessLogger;
-import org.hswebframework.web.model.authorization.UserModel;
 import org.hswebframework.web.service.authorization.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 
+import java.util.List;
+
 import static org.hswebframework.web.controller.message.ResponseMessage.ok;
 
 /**
- * TODO 完成注释
+ * 用户管理控制器
  *
  * @author zhouhao
  */
@@ -55,6 +59,8 @@ public class UserController implements
 
     private UserService userService;
 
+    private UserTokenManager userTokenManager;
+
     @Override
     @SuppressWarnings("unchecked")
     public UserService getService() {
@@ -66,6 +72,29 @@ public class UserController implements
         this.userService = userService;
     }
 
+    @Autowired(required = false)
+    public void setUserTokenManager(UserTokenManager userTokenManager) {
+        this.userTokenManager = userTokenManager;
+    }
+
+    @GetMapping("/tokens")
+    @Authorize(action = Permission.ACTION_QUERY)
+    @AccessLogger("获取所有已登录用户的信息")
+    public ResponseMessage<List<UserToken>> userTokens() {
+        if (userTokenManager == null) throw new UnsupportedOperationException("userTokenManager is null");
+
+        return ok(userTokenManager.allLoggedUser());
+    }
+
+    @PutMapping("/tokens/{token}/{state}")
+    @Authorize(action = "change-state")
+    @AccessLogger("修改token的状态")
+    public ResponseMessage<List<UserToken>> makeOffline(@PathVariable String token, @PathVariable TokenState state) {
+        if (userTokenManager == null) throw new UnsupportedOperationException("userTokenManager is null");
+        userTokenManager.changeTokenState(token, state);
+        return ok();
+    }
+
     @Override
     public ResponseMessage<PagerResult<UserEntity>> list(QueryParamEntity param) {
         param.excludes("password", "salt");
@@ -96,7 +125,7 @@ public class UserController implements
     public ResponseMessage<Void> updateLoginUserPassword(@RequestParam String password,
                                                          @RequestParam String oldPassword) {
 
-        Authentication authentication = Authentication.current().orElseThrow(AuthorizeException::new);
+        Authentication authentication = Authentication.current().orElseThrow(UnAuthorizedException::new);
         getService().updatePassword(authentication.getUser().getId(), oldPassword, password);
         return ok();
     }

+ 7 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-service/hsweb-system-authorization-service-simple/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthorizationSettingService.java

@@ -317,13 +317,18 @@ public class SimpleAuthorizationSettingService extends GenericEntityService<Auth
                 detail.setDataAccesses(detail
                         .getDataAccesses()
                         .stream()
-                        .filter(access -> entity.getSupportDataAccessTypes().contains(access.getType()))
+                        .filter(access ->
+                                //以设置支持的权限开头就认为拥有该权限
+                                //比如支持的权限为CUSTOM_SCOPE_ORG_SCOPE
+                                //设置的权限为CUSTOM_SCOPE 则通过检验
+                                entity.getSupportDataAccessTypes().stream()
+                                        .anyMatch(type -> type.startsWith(access.getType())))
                         .collect(Collectors.toList()));
             }
             return true;
         }).collect(Collectors.toList());
 
-        //权限
+        //全部权限设置
         Map<String, List<AuthorizationSettingDetailEntity>> settings = detailList
                 .stream()
                 .collect(Collectors.groupingBy(AuthorizationSettingDetailEntity::getPermissionId));

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/pom.xml

@@ -68,7 +68,7 @@
 
         <!--<dependency>-->
             <!--<groupId>org.hswebframework.web</groupId>-->
-            <!--<artifactId>hsweb-authorization-shiro</artifactId>-->
+            <!--<artifactId>hsweb-authorization-basic</artifactId>-->
             <!--<version>${project.version}</version>-->
             <!--<scope>test</scope>-->
         <!--</dependency>-->

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/main/resources/hsweb-starter.js

@@ -115,7 +115,7 @@ function install(context) {
         .addColumn().name("u_id").varchar(32).notNull().primaryKey().comment("uid").commit()
         .addColumn().name("name").varchar(64).notNull().comment("名称").commit()
         .addColumn().name("parent_id").varchar(32).comment("父级ID").commit()
-        .addColumn().name("permission_id").varchar(32).comment("权限ID").commit()
+        .addColumn().name("permission_id").varchar(2048).comment("权限ID").commit()
         .addColumn().name("path").varchar(2048).notNull().comment("树编码").commit()
         .addColumn().name("sort_index").number(32).notNull().comment("树编码").commit()
         .addColumn().name("describe").varchar(128).comment("备注").commit()

+ 2 - 5
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/src/test/java/org/hswebframework/web/starter/authorization/LoginTests.java

@@ -18,16 +18,12 @@
 package org.hswebframework.web.starter.authorization;
 
 import com.alibaba.fastjson.JSONObject;
-import org.apache.commons.codec.binary.Base64;
-import org.hswebframework.expands.security.Encrypt;
-import org.hswebframework.expands.security.rsa.RSAPublicEncrypt;
 import org.hswebframework.web.entity.authorization.UserEntity;
 import org.hswebframework.web.service.authorization.UserService;
 import org.hswebframework.web.tests.SimpleWebApplicationTests;
 import org.junit.After;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.Assert;
 
 import java.sql.SQLException;
 
@@ -61,6 +57,7 @@ public class LoginTests extends SimpleWebApplicationTests {
             builder.param("password", "password_1234");
         }).exec().resultAsJson();
 
-        org.junit.Assert.assertEquals(json.get("result"), userEntity.getId());
+        org.junit.Assert.assertEquals(userEntity.getId(), json.getJSONObject("result").getString("userId"));
+
     }
 }

+ 2 - 2
hsweb-system/hsweb-system-oauth2-server/hsweb-system-oauth2-server-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2AuthorizeController.java

@@ -20,9 +20,9 @@ package org.hswebframework.web.authorization.oauth2.controller;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.hswebframework.web.AuthorizeException;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.authorization.oauth2.server.OAuth2AccessToken;
 import org.hswebframework.web.authorization.oauth2.server.support.OAuth2Granter;
 import org.hswebframework.web.authorization.oauth2.server.support.code.AuthorizationCodeRequest;
@@ -62,7 +62,7 @@ public class OAuth2AuthorizeController {
             @RequestParam("redirect_uri") String redirectUri,
             @RequestParam(value = "state", required = false) String state,
             HttpServletRequest request) {
-        Authentication authentication = Authentication.current().orElseThrow(AuthorizeException::new);
+        Authentication authentication = Authentication.current().orElseThrow(UnAuthorizedException::new);
 
         AuthorizationCodeRequest codeRequest = new HttpAuthorizationCodeRequest(authentication.getUser().getId(), request);
 

+ 3 - 3
hsweb-system/hsweb-system-oauth2-server/hsweb-system-oauth2-server-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2UserInfoController.java

@@ -20,9 +20,9 @@ package org.hswebframework.web.authorization.oauth2.controller;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
-import org.hswebframework.web.AuthorizeException;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationHolder;
+import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.authorization.oauth2.server.OAuth2AccessToken;
 import org.hswebframework.web.authorization.oauth2.server.token.AccessTokenService;
 import org.springframework.web.bind.annotation.*;
@@ -48,7 +48,7 @@ public class OAuth2UserInfoController {
     public Authentication getLoginUser(@RequestParam("access_token") String access_token) {
         OAuth2AccessToken auth2AccessEntity = accessTokenService.getTokenByAccessToken(access_token);
         if (null == auth2AccessEntity) {
-            throw new AuthorizeException();
+            throw new UnAuthorizedException();
         }
         return AuthenticationHolder.get(auth2AccessEntity.getOwnerId());
     }
@@ -60,7 +60,7 @@ public class OAuth2UserInfoController {
             @RequestParam("access_token") String access_token) {
         OAuth2AccessToken auth2AccessEntity = accessTokenService.getTokenByAccessToken(access_token);
         if (null == auth2AccessEntity) {
-            throw new AuthorizeException();
+            throw new UnAuthorizedException();
         }
         return AuthenticationHolder.get(userId);
     }

+ 16 - 3
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/OrganizationalAuthorizationAutoConfiguration.java

@@ -18,9 +18,16 @@ import org.springframework.context.annotation.Configuration;
 public class OrganizationalAuthorizationAutoConfiguration implements BeanPostProcessor {
 
     @Bean
-    @ConditionalOnMissingBean(AreaScopeDataAccessHandler.class)
-    public AreaScopeDataAccessHandler areaScopeDataAccessHandler() {
-        return new AreaScopeDataAccessHandler();
+    @ConditionalOnMissingBean(DistrictScopeDataAccessHandler.class)
+    public DistrictScopeDataAccessHandler areaScopeDataAccessHandler() {
+        return new DistrictScopeDataAccessHandler();
+    }
+
+
+    @Bean
+    @ConditionalOnMissingBean(CustomScopeHandler.class)
+    public CustomScopeHandler customScopeHandler() {
+        return new CustomScopeHandler();
     }
 
     @Bean
@@ -53,6 +60,12 @@ public class OrganizationalAuthorizationAutoConfiguration implements BeanPostPro
         return new ScopeDataAccessConfigConvert();
     }
 
+    @Bean
+    @ConditionalOnMissingBean(CustomScopeDataAccessConfigConvert.class)
+    public CustomScopeDataAccessConfigConvert customScopeDataAccessConfigConvert() {
+        return new CustomScopeDataAccessConfigConvert();
+    }
+
     @Override
     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
         return bean;

+ 1 - 1
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/access/DataAccessType.java

@@ -40,6 +40,6 @@ public interface DataAccessType extends Serializable {
     /**
      * 自定义范围
      */
-    String SCOPE_TYPE_CUSTOM    = "CUSTOM";
+    String SCOPE_TYPE_CUSTOM    = "CUSTOM_SCOPE";
 
 }

+ 42 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/CustomScope.java

@@ -0,0 +1,42 @@
+package org.hswebframework.web.organizational.authorization.simple;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * 自定义范围
+ *
+ * @author zhouhao
+ */
+public class CustomScope implements Serializable {
+
+    private String type;
+
+    private Set<String> ids;
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Set<String> getIds() {
+        return ids;
+    }
+
+    public void setIds(Set<String> ids) {
+        this.ids = ids;
+    }
+
+    @Override
+    public int hashCode() {
+        return (type + "" + ids).hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        return obj instanceof CustomScope && hashCode() == obj.hashCode();
+    }
+}

+ 35 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/CustomScopeDataAccessConfigConvert.java

@@ -0,0 +1,35 @@
+package org.hswebframework.web.organizational.authorization.simple;
+
+import com.alibaba.fastjson.JSON;
+import org.hswebframework.web.authorization.access.DataAccessConfig;
+import org.hswebframework.web.authorization.simple.builder.DataAccessConfigConvert;
+import org.hswebframework.web.organizational.authorization.access.DataAccessType;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.hswebframework.web.organizational.authorization.access.DataAccessType.*;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class CustomScopeDataAccessConfigConvert implements DataAccessConfigConvert {
+    private static final List<String> supportTypes = Arrays.asList(
+            DataAccessType.SCOPE_TYPE_CUSTOM
+    );
+
+    @Override
+    public boolean isSupport(String type, String action, String config) {
+        return supportTypes.contains(type);
+    }
+
+    @Override
+    public DataAccessConfig convert(String type, String action, String config) {
+        SimpleCustomScopeDataAccessConfig accessConfig = JSON.parseObject(config, SimpleCustomScopeDataAccessConfig.class);
+        accessConfig.setAction(action);
+
+        return accessConfig;
+    }
+}

+ 28 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/SimpleCustomScopeDataAccessConfig.java

@@ -0,0 +1,28 @@
+package org.hswebframework.web.organizational.authorization.simple;
+
+import org.hswebframework.web.authorization.simple.AbstractDataAccessConfig;
+import org.hswebframework.web.organizational.authorization.access.DataAccessType;
+
+import java.util.Set;
+
+/**
+ * 自定义范围配置
+ *
+ * @author zhouhao
+ */
+public class SimpleCustomScopeDataAccessConfig extends AbstractDataAccessConfig {
+    private Set<CustomScope> scope;
+
+    @Override
+    public String getType() {
+        return DataAccessType.SCOPE_TYPE_CUSTOM;
+    }
+
+    public Set<CustomScope> getScope() {
+        return scope;
+    }
+
+    public void setScope(Set<CustomScope> scope) {
+        this.scope = scope;
+    }
+}

+ 7 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/SimpleScopeDataAccessConfig.java

@@ -28,6 +28,13 @@ public class SimpleScopeDataAccessConfig extends AbstractDataAccessConfig implem
         this.scope = scope;
     }
 
+    public SimpleScopeDataAccessConfig(String type, String scopeType, String action, Set<Object> scope) {
+        this.scopeType = scopeType;
+        this.scope = scope;
+        this.type = type;
+        setAction(action);
+    }
+
     @Override
     public String getScopeType() {
         return scopeType;

+ 23 - 27
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/AbstractScopeDataAccessHandler.java

@@ -6,14 +6,10 @@ import org.hswebframework.web.authorization.Permission;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
 import org.hswebframework.web.authorization.access.ScopeDataAccessConfig;
-import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.commons.entity.Entity;
 import org.hswebframework.web.commons.entity.param.QueryParamEntity;
 import org.hswebframework.web.controller.QueryController;
-import org.hswebframework.web.entity.organizational.OrganizationalEntity;
-import org.hswebframework.web.entity.organizational.authorization.OrgAttachEntity;
 import org.hswebframework.web.organizational.authorization.PersonnelAuthorization;
 import org.hswebframework.web.organizational.authorization.access.DataAccessType;
 import org.hswebframework.web.service.QueryService;
@@ -43,7 +39,7 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
 
     protected abstract void applyScopeProperty(E entity, String value);
 
-    protected abstract Term createQueryTerm(Set<String> scope);
+    protected abstract Term createQueryTerm(Set<String> scope,AuthorizingContext context);
 
     protected abstract Set<String> getTryOperationScope(String scopeType, PersonnelAuthorization authorization);
 
@@ -53,7 +49,7 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
     }
 
     @Override
-    public boolean handle(DataAccessConfig access, MethodInterceptorParamContext context) {
+    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
         ScopeDataAccessConfig accessConfig = ((ScopeDataAccessConfig) access);
         switch (accessConfig.getAction()) {
             case Permission.ACTION_QUERY:
@@ -73,20 +69,20 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
                 .orElseThrow(UnsupportedOperationException::new); // TODO: 17-5-23 其他异常?
     }
 
-    protected boolean handleAdd(ScopeDataAccessConfig access, MethodInterceptorParamContext context) {
+    protected boolean handleAdd(ScopeDataAccessConfig access, AuthorizingContext context) {
         PersonnelAuthorization authorization = getPersonnelAuthorization();
         Set<String> scopes = authorization.getRootOrgId();
         String scope = null;
         if (scopes.size() == 0) return true;
         else if (scopes.size() == 1) scope = scopes.iterator().next();
         else logger.warn("existing many scope :{} , try use config.", scopes);
-        scopes = access.getScope().stream().map(String::valueOf).collect(Collectors.toSet());
+        scopes = getTryOperationScope(access).stream().map(String::valueOf).collect(Collectors.toSet());
         if (scope == null && scopes.size() == 1) {
             scope = scopes.iterator().next();
         }
         if (scope != null) {
             String finalScopeId = scope;
-            context.getParams().values().stream()
+            context.getParamContext().getParams().values().stream()
                     .filter(getEntityClass()::isInstance)
                     .map(getEntityClass()::cast)
                     .forEach(entity -> applyScopeProperty(entity, finalScopeId));
@@ -96,11 +92,16 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
         return defaultSuccessOnError;
     }
 
-    protected boolean handleRW(ScopeDataAccessConfig access, MethodInterceptorParamContext context) {
+    protected boolean handleRW(ScopeDataAccessConfig access, AuthorizingContext context) {
         //获取注解
-        RequiresDataAccess dataAccess = context.getAnnotation(RequiresDataAccess.class);
-        Object id = context.<String>getParameter(dataAccess.idParamName()).orElse(null);
-        Object controller = context.getTarget();
+        Object id = context.getParamContext()
+                .<String>getParameter(
+                        context.getDefinition()
+                                .getDataAccessDefinition()
+                                .getIdParameterName())
+                .orElse(null);
+
+        Object controller = context.getParamContext().getTarget();
         Set<String> ids = getTryOperationScope(access);
         String errorMsg;
         //通过QueryController获取QueryService
@@ -109,14 +110,10 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
             //判断是否满足条件(泛型为 getEntityClass)
             Class entityType = ClassUtils.getGenericType(controller.getClass(), 0);
             if (ClassUtils.instanceOf(entityType, getEntityClass())) {
-                QueryService<E, Object> queryService =
-                        ((QueryController<E, Object, Entity>) controller).getService();
+                @SuppressWarnings("unchecked")
+                QueryService<E, Object> queryService = ((QueryController<E, Object, Entity>) controller).getService();
                 E oldData = queryService.selectByPk(id);
-                if (oldData != null && ids.contains(getOperationScope(oldData))) {
-                    return false;
-                } else {
-                    return true;
-                }
+                return !(oldData != null && !ids.contains(getOperationScope(oldData)));
             } else {
                 errorMsg = "GenericType[0] not instance of " + getEntityClass();
             }
@@ -133,8 +130,8 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
         return getTryOperationScope(access.getScopeType(), getPersonnelAuthorization());
     }
 
-    protected boolean handleQuery(ScopeDataAccessConfig access, MethodInterceptorParamContext context) {
-        Entity entity = context.getParams()
+    protected boolean handleQuery(ScopeDataAccessConfig access, AuthorizingContext context) {
+        Entity entity = context.getParamContext().getParams()
                 .values().stream()
                 .filter(Entity.class::isInstance)
                 .map(Entity.class::cast)
@@ -160,7 +157,7 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
             queryParamEntity.setTerms(new ArrayList<>());
             //添加一个查询条件
             queryParamEntity
-                    .addTerm(createQueryTerm(scope))
+                    .addTerm(createQueryTerm(scope,context))
                     //客户端提交的参数 作为嵌套参数
                     .nest().setTerms(oldParam);
         } else {
@@ -169,9 +166,8 @@ public abstract class AbstractScopeDataAccessHandler<E> implements DataAccessHan
         return true;
     }
 
-    protected boolean genericTypeInstanceOf(Class type) {
-        MethodInterceptorHolder holder = MethodInterceptorHolder.current();
-        Class entity = ClassUtils.getGenericType(holder.getTarget().getClass());
+    protected boolean genericTypeInstanceOf(Class type, AuthorizingContext context) {
+        Class entity = ClassUtils.getGenericType(context.getParamContext().getTarget().getClass());
         return null != entity && ClassUtils.instanceOf(entity, type);
     }
 }

+ 43 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/CustomScopeHandler.java

@@ -0,0 +1,43 @@
+package org.hswebframework.web.organizational.authorization.simple.handler;
+
+import org.hswebframework.web.authorization.access.DataAccessConfig;
+import org.hswebframework.web.authorization.access.DataAccessHandler;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
+import org.hswebframework.web.organizational.authorization.access.DataAccessType;
+import org.hswebframework.web.organizational.authorization.simple.SimpleCustomScopeDataAccessConfig;
+import org.hswebframework.web.organizational.authorization.simple.SimpleScopeDataAccessConfig;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class CustomScopeHandler implements DataAccessHandler {
+
+    private List<DataAccessHandler> handlers = Arrays.asList(
+            new DistrictScopeDataAccessHandler(),
+            new DepartmentScopeDataAccessHandler(),
+            new OrgScopeDataAccessHandler(),
+            new PersonScopeDataAccessHandler(),
+            new PositionScopeDataAccessHandler()
+    );
+
+    @Override
+    public boolean isSupport(DataAccessConfig access) {
+        return access instanceof SimpleCustomScopeDataAccessConfig;
+    }
+
+    @Override
+    public boolean handle(DataAccessConfig access, AuthorizingContext context) {
+        return ((SimpleCustomScopeDataAccessConfig) access).getScope()
+                .stream()
+                .map(scope -> new SimpleScopeDataAccessConfig(scope.getType(), DataAccessType.SCOPE_TYPE_CUSTOM, access.getAction(), new HashSet<>(scope.getIds())))
+                .allMatch(accessConfig -> handlers.stream()
+                        .filter(handler -> handler.isSupport(accessConfig))
+                        .allMatch(handler -> handler.handle(accessConfig, context)));
+    }
+}

+ 3 - 2
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/DepartmentScopeDataAccessHandler.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.organizational.authorization.simple.handler;
 
 import org.hsweb.ezorm.core.param.Term;
 import org.hsweb.ezorm.core.param.TermType;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.entity.organizational.DepartmentEntity;
 import org.hswebframework.web.entity.organizational.OrganizationalEntity;
 import org.hswebframework.web.entity.organizational.authorization.DepartmentAttachEntity;
@@ -54,9 +55,9 @@ public class DepartmentScopeDataAccessHandler extends AbstractScopeDataAccessHan
     }
 
     @Override
-    protected Term createQueryTerm(Set<String> scope) {
+    protected Term createQueryTerm(Set<String> scope, AuthorizingContext context) {
         Term term = new Term();
-        if (genericTypeInstanceOf(DepartmentEntity.class)) {
+        if (genericTypeInstanceOf(DepartmentEntity.class,context)) {
             term.setColumn(DepartmentEntity.id);
         } else {
             term.setColumn(DepartmentAttachEntity.departmentId);

+ 3 - 2
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/AreaScopeDataAccessHandler.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.organizational.authorization.simple.handler;
 
 import org.hsweb.ezorm.core.param.Term;
 import org.hsweb.ezorm.core.param.TermType;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.entity.organizational.authorization.DistrictAttachEntity;
 import org.hswebframework.web.organizational.authorization.PersonnelAuthorization;
 
@@ -15,7 +16,7 @@ import static org.hswebframework.web.organizational.authorization.access.DataAcc
  *
  * @author zhouhao
  */
-public class AreaScopeDataAccessHandler extends AbstractScopeDataAccessHandler<DistrictAttachEntity> {
+public class DistrictScopeDataAccessHandler extends AbstractScopeDataAccessHandler<DistrictAttachEntity> {
     @Override
     protected Class<DistrictAttachEntity> getEntityClass() {
         return DistrictAttachEntity.class;
@@ -49,7 +50,7 @@ public class AreaScopeDataAccessHandler extends AbstractScopeDataAccessHandler<D
     }
 
     @Override
-    protected Term createQueryTerm(Set<String> scope) {
+    protected Term createQueryTerm(Set<String> scope, AuthorizingContext context) {
         Term term = new Term();
         term.setColumn(DistrictAttachEntity.districtId);
         term.setTermType(TermType.in);

+ 3 - 6
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/OrgScopeDataAccessHandler.java

@@ -2,11 +2,8 @@ package org.hswebframework.web.organizational.authorization.simple.handler;
 
 import org.hsweb.ezorm.core.param.Term;
 import org.hsweb.ezorm.core.param.TermType;
-import org.hswebframework.utils.ClassUtils;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.entity.organizational.OrganizationalEntity;
-import org.hswebframework.web.entity.organizational.SimpleOrganizationalEntity;
 import org.hswebframework.web.entity.organizational.authorization.OrgAttachEntity;
 import org.hswebframework.web.organizational.authorization.PersonnelAuthorization;
 import org.hswebframework.web.organizational.authorization.access.DataAccessType;
@@ -56,9 +53,9 @@ public class OrgScopeDataAccessHandler extends AbstractScopeDataAccessHandler<Or
     }
 
     @Override
-    protected Term createQueryTerm(Set<String> scope) {
+    protected Term createQueryTerm(Set<String> scope, AuthorizingContext context) {
         Term term = new Term();
-        if (genericTypeInstanceOf(OrganizationalEntity.class)) {
+        if (genericTypeInstanceOf(OrganizationalEntity.class,context)) {
             term.setColumn(OrganizationalEntity.id);
         } else {
             term.setColumn(OrgAttachEntity.orgId);

+ 2 - 1
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/PersonScopeDataAccessHandler.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.organizational.authorization.simple.handler;
 
 import org.hsweb.ezorm.core.param.Term;
 import org.hsweb.ezorm.core.param.TermType;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.entity.organizational.authorization.PersonAttachEntity;
 import org.hswebframework.web.organizational.authorization.PersonnelAuthorization;
 import org.hswebframework.web.organizational.authorization.access.DataAccessType;
@@ -51,7 +52,7 @@ public class PersonScopeDataAccessHandler extends AbstractScopeDataAccessHandler
     }
 
     @Override
-    protected Term createQueryTerm(Set<String> scope) {
+    protected Term createQueryTerm(Set<String> scope, AuthorizingContext context) {
         Term term = new Term();
         term.setColumn(PersonAttachEntity.personId);
         term.setTermType(TermType.in);

+ 3 - 2
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/simple/handler/PositionScopeDataAccessHandler.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.organizational.authorization.simple.handler;
 
 import org.hsweb.ezorm.core.param.Term;
 import org.hsweb.ezorm.core.param.TermType;
+import org.hswebframework.web.authorization.define.AuthorizingContext;
 import org.hswebframework.web.entity.organizational.PositionEntity;
 import org.hswebframework.web.entity.organizational.authorization.PositionAttachEntity;
 import org.hswebframework.web.organizational.authorization.PersonnelAuthorization;
@@ -52,9 +53,9 @@ public class PositionScopeDataAccessHandler extends AbstractScopeDataAccessHandl
     }
 
     @Override
-    protected Term createQueryTerm(Set<String> scope) {
+    protected Term createQueryTerm(Set<String> scope, AuthorizingContext context) {
         Term term = new Term();
-        if (genericTypeInstanceOf(PositionEntity.class)) {
+        if (genericTypeInstanceOf(PositionEntity.class,context)) {
             term.setColumn(PositionEntity.id);
         } else {
             term.setColumn(PositionAttachEntity.positionId);

+ 2 - 0
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-service/hsweb-system-organizational-service-simple/src/main/java/org/hswebframework/web/service/organizational/simple/SimplePersonService.java

@@ -105,6 +105,7 @@ public class SimplePersonService extends EnableCacheGenericEntityService<PersonE
     @Override
     @Caching(evict = {
             @CacheEvict(key = "'id:'+#result"),
+            @CacheEvict(key = "'auth:persion-id'+#result"),
             @CacheEvict(key = "'auth-bind'+#result")
     })
     public String insert(PersonAuthBindEntity authBindEntity) {
@@ -123,6 +124,7 @@ public class SimplePersonService extends EnableCacheGenericEntityService<PersonE
     @Override
     @Caching(evict = {
             @CacheEvict(key = "'id:'+#authBindEntity.id"),
+            @CacheEvict(key = "'auth:persion-id'+#authBindEntity.id"),
             @CacheEvict(key = "'auth-bind'+#authBindEntity.id")
     })
     public int updateByPk(PersonAuthBindEntity authBindEntity) {