Bladeren bron

完善basic权限

zhouhao 7 jaren geleden
bovenliggende
commit
7940a6a948
33 gewijzigde bestanden met toevoegingen van 1069 en 110 verwijderingen
  1. 5 2
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationHolder.java
  2. 0 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/define/AuthorizeDefinition.java
  3. 2 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/exception/AuthorizationException.java
  4. 2 2
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenManager.java
  5. 29 0
      hsweb-authorization/hsweb-authorization-basic/pom.xml
  6. 49 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java
  7. 1 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/AopMethodAuthorizeDefinitionParser.java
  8. 68 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java
  9. 33 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AopAuthorizeAutoConfiguration.java
  10. 105 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java
  11. 17 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/EnableAopAuthorize.java
  12. 0 65
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/AnnotationAuthorizeDefinitionParser.java
  13. 7 4
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/DefaultBasicAuthorizeDefinition.java
  14. 1 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/AuthorizingContext.java
  15. 0 3
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/AuthorizingHandler.java
  16. 37 27
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java
  17. 44 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/CustomDataAccessHandler.java
  18. 59 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java
  19. 86 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldFilterDataAccessHandler.java
  20. 114 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/FieldScopeDataAccessHandler.java
  21. 129 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/OwnCreatedDataAccessHandler.java
  22. 41 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/ScriptDataAccessHandler.java
  23. 28 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/DefaultUserTokenParser.java
  24. 49 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignIn.java
  25. 31 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignOut.java
  26. 36 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenAuthenticationSupplier.java
  27. 25 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenHolder.java
  28. 13 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenParser.java
  29. 47 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/WebUserTokenInterceptor.java
  30. 7 1
      hsweb-examples/hsweb-examples-simple/pom.xml
  31. 2 0
      hsweb-examples/hsweb-examples-simple/src/main/java/org/hswebframework/web/example/simple/SpringBootExample.java
  32. 0 1
      hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/PersonnelAuthorization.java
  33. 2 2
      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

+ 5 - 2
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationHolder.java

@@ -52,10 +52,13 @@ public final class AuthenticationHolder {
     private static Authentication get(Function<AuthenticationSupplier, Authentication> function) {
         lock.readLock().lock();
         try {
-            return suppliers.stream()
+            Authentication authentication = suppliers.stream()
                     .map(function)
                     .filter(Objects::nonNull)
-                    .findFirst().orElse(null);
+                    .findFirst()
+                    .orElse(null);
+
+            return authentication;
         } finally {
             lock.readLock().unlock();
         }

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

@@ -11,7 +11,6 @@ import java.util.Set;
  * 权限控制定义,定义权限控制的方式
  *
  * @author zhouhao
- * @see AopMethodAuthorizeDefinitionParser
  * @since 3.0
  */
 public interface AuthorizeDefinition {

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

@@ -6,6 +6,8 @@ package org.hswebframework.web.authorization.exception;
  */
 public class AuthorizationException extends RuntimeException {
 
+    public AuthorizationException() {
+    }
 
     public AuthorizationException(String message) {
         super(message);

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

@@ -77,13 +77,13 @@ public interface UserTokenManager {
      *
      * @param userId 用户ID
      */
-    void logoutByUserId(String userId);
+    void signOutByUserId(String userId);
 
     /**
      * 根据token删除
      * @param token
      */
-    void logoutByToken(String token);
+    void signOutByToken(String token);
 
     /**
      * 登记一个用户的token

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

@@ -21,6 +21,35 @@
             <groupId>org.hswebframework</groupId>
             <artifactId>hsweb-expands-script</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-easy-orm-rdb</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-controller</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 49 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/AopAuthorizingController.java

@@ -0,0 +1,49 @@
+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.basic.handler.AuthorizingHandler;
+import org.hswebframework.web.authorization.define.AuthorizeDefinition;
+import org.hswebframework.web.authorization.exception.AuthorizationException;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorHolder;
+import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
+import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author zhouhao
+ */
+public class AopAuthorizingController extends StaticMethodMatcherPointcutAdvisor {
+
+    public AopAuthorizingController(AuthorizingHandler authorizingHandler, AopMethodAuthorizeDefinitionParser aopMethodAuthorizeDefinitionParser) {
+        super((MethodInterceptor) methodInvocation -> {
+
+            MethodInterceptorHolder holder = MethodInterceptorHolder.create(methodInvocation);
+
+            MethodInterceptorParamContext 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);
+            }
+            return methodInvocation.proceed();
+        });
+    }
+
+    @Override
+    public boolean matches(Method method, Class<?> aClass) {
+        //对controller进行控制
+        return AopUtils.findAnnotation(aClass, Controller.class) != null
+                || AopUtils.findAnnotation(aClass, RestController.class) != null;
+    }
+}

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

@@ -1,4 +1,4 @@
-package org.hswebframework.web.authorization.basic.define;
+package org.hswebframework.web.authorization.basic.aop;
 
 import org.hswebframework.web.authorization.define.AuthorizeDefinition;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;

+ 68 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/aop/DefaultAopMethodAuthorizeDefinitionParser.java

@@ -0,0 +1,68 @@
+package org.hswebframework.web.authorization.basic.aop;
+
+import org.hswebframework.web.AopUtils;
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
+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 java.lang.reflect.Method;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 注解权限控制定义解析器,通过判断方法上的注解来获取权限控制的方式
+ *
+ * @author zhouhao
+ * @see AopMethodAuthorizeDefinitionParser
+ * @see AuthorizeDefinition
+ */
+
+public class DefaultAopMethodAuthorizeDefinitionParser implements AopMethodAuthorizeDefinitionParser {
+
+    private Map<Method, AuthorizeDefinition> cache = new ConcurrentHashMap<>();
+
+    @Override
+    public AuthorizeDefinition parse(MethodInterceptorParamContext paramContext) {
+
+        AuthorizeDefinition definition = cache.get(paramContext.getMethod());
+        if (definition != null) return definition instanceof EmptyAuthorizeDefinition ? null : definition;
+
+
+        Authorize classAuth = AopUtils.findAnnotation(paramContext.getTarget().getClass(), Authorize.class);
+        Authorize methodAuth = AopUtils.findMethodAnnotation(paramContext.getTarget().getClass(), paramContext.getMethod(), Authorize.class);
+        RequiresDataAccess classDataAccess = AopUtils.findAnnotation(paramContext.getTarget().getClass(), RequiresDataAccess.class);
+        RequiresDataAccess methodDataAccess = AopUtils.findMethodAnnotation(paramContext.getTarget().getClass(), paramContext.getMethod(), RequiresDataAccess.class);
+
+        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);
+            return null;
+        }
+
+        if (methodAuth != null && methodAuth.ignore()) {
+            cache.put(paramContext.getMethod(), EmptyAuthorizeDefinition.instance);
+            return null;
+        }
+
+
+        DefaultBasicAuthorizeDefinition authorizeDefinition = new DefaultBasicAuthorizeDefinition();
+
+        authorizeDefinition.put(classAuth);
+        authorizeDefinition.put(methodAuth);
+
+        authorizeDefinition.put(expression);
+
+        authorizeDefinition.put(classDataAccess);
+        authorizeDefinition.put(methodDataAccess);
+
+        cache.put(paramContext.getMethod(), authorizeDefinition);
+
+        return authorizeDefinition;
+    }
+
+}

+ 33 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AopAuthorizeAutoConfiguration.java

@@ -0,0 +1,33 @@
+package org.hswebframework.web.authorization.basic.configuration;
+
+import org.hswebframework.web.authorization.access.DataAccessController;
+import org.hswebframework.web.authorization.basic.aop.AopAuthorizingController;
+import org.hswebframework.web.authorization.basic.aop.AopMethodAuthorizeDefinitionParser;
+import org.hswebframework.web.authorization.basic.aop.DefaultAopMethodAuthorizeDefinitionParser;
+import org.hswebframework.web.authorization.basic.handler.AuthorizingHandler;
+import org.hswebframework.web.authorization.basic.handler.DefaultAuthorizingHandler;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author zhouhao
+ */
+@Configuration
+@AutoConfigureAfter(AuthorizingHandlerAutoConfiguration.class)
+public class AopAuthorizeAutoConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean(AopMethodAuthorizeDefinitionParser.class)
+    public DefaultAopMethodAuthorizeDefinitionParser defaultAopMethodAuthorizeDefinitionParser() {
+        return new DefaultAopMethodAuthorizeDefinitionParser();
+    }
+
+
+    @Bean
+    public AopAuthorizingController aopAuthorizingController(AuthorizingHandler authorizingHandler,
+                                                             AopMethodAuthorizeDefinitionParser aopMethodAuthorizeDefinitionParser) {
+        return new AopAuthorizingController(authorizingHandler, aopMethodAuthorizeDefinitionParser);
+    }
+}

+ 105 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java

@@ -0,0 +1,105 @@
+package org.hswebframework.web.authorization.basic.configuration;
+
+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.basic.handler.DefaultAuthorizingHandler;
+import org.hswebframework.web.authorization.basic.handler.access.DefaultDataAccessController;
+import org.hswebframework.web.authorization.basic.web.*;
+import org.hswebframework.web.authorization.token.MemoryUserTokenManager;
+import org.hswebframework.web.authorization.token.UserTokenManager;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Configuration
+public class AuthorizingHandlerAutoConfiguration {
+
+    @Bean
+    public DefaultDataAccessController dataAccessController() {
+        return new DefaultDataAccessController();
+    }
+
+    @Bean
+    public DefaultAuthorizingHandler authorizingHandler(DataAccessController dataAccessController) {
+        return new DefaultAuthorizingHandler(dataAccessController);
+    }
+
+    @Bean
+    public UserTokenAuthenticationSupplier userTokenAuthenticationSupplier(AuthenticationManager authenticationManager) {
+        return new UserTokenAuthenticationSupplier(authenticationManager);
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(UserTokenParser.class)
+    public UserTokenParser userTokenParser() {
+        return new DefaultUserTokenParser();
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(UserTokenManager.class)
+    @ConfigurationProperties(prefix = "hsweb.authorize")
+    public UserTokenManager userTokenManager() {
+        return new MemoryUserTokenManager();
+    }
+
+    @Bean
+    public WebMvcConfigurer webUserTokenInterceptorConfigurer(UserTokenManager userTokenManager,
+                                                              UserTokenParser userTokenParser) {
+        return new WebMvcConfigurerAdapter() {
+            @Override
+            public void addInterceptors(InterceptorRegistry registry) {
+                registry.addInterceptor(new WebUserTokenInterceptor(userTokenManager, userTokenParser));
+                super.addInterceptors(registry);
+            }
+        };
+    }
+
+    @Bean
+    public UserOnSignIn userOnSignIn(UserTokenManager userTokenManager) {
+        return new UserOnSignIn(userTokenManager);
+    }
+
+    @Bean
+    public UserOnSignOut userOnSignOut(UserTokenManager userTokenManager) {
+        return new UserOnSignOut(userTokenManager);
+    }
+
+    @Configuration
+    public static class DataAccessHandlerProcessor implements BeanPostProcessor {
+
+        @Autowired
+        private DefaultDataAccessController defaultDataAccessController;
+
+        @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));
+            }
+            if (bean instanceof AuthenticationSupplier) {
+                AuthenticationHolder.addSupplier(((AuthenticationSupplier) bean));
+            }
+            return bean;
+        }
+    }
+}

+ 17 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/EnableAopAuthorize.java

@@ -0,0 +1,17 @@
+package org.hswebframework.web.authorization.basic.configuration;
+
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+
+import java.lang.annotation.*;
+
+/**
+ * @author zhouhao
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@ImportAutoConfiguration(AopAuthorizeAutoConfiguration.class)
+public @interface EnableAopAuthorize {
+
+}

+ 0 - 65
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/define/AnnotationAuthorizeDefinitionParser.java

@@ -1,65 +0,0 @@
-package org.hswebframework.web.authorization.basic.define;
-
-import org.hswebframework.web.AopUtils;
-import org.hswebframework.web.authorization.annotation.Authorize;
-import org.hswebframework.web.authorization.annotation.RequiresDataAccess;
-import org.hswebframework.web.authorization.annotation.RequiresExpression;
-import org.hswebframework.web.authorization.define.AuthorizeDefinition;
-import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * 注解权限控制定义解析器,通过判断方法上的注解来获取权限控制的方式
- * @author zhouhao
- * @see AopMethodAuthorizeDefinitionParser
- * @see AuthorizeDefinition
- */
-
-public class AnnotationAuthorizeDefinitionParser implements AopMethodAuthorizeDefinitionParser {
-
-    private Map<Method,AuthorizeDefinition> cache=new ConcurrentHashMap<>();
-
-    @Override
-    public AuthorizeDefinition parse(MethodInterceptorParamContext paramContext) {
-
-        AuthorizeDefinition definition = cache.get(paramContext.getMethod());
-        if(definition!=null)return definition instanceof EmptyAuthorizeDefinition ?null:definition;
-
-
-        Authorize classAuth= AopUtils.findAnnotation(paramContext.getTarget().getClass(),Authorize.class);
-        Authorize methodAuth=AopUtils.findMethodAnnotation(paramContext.getTarget().getClass(),paramContext.getMethod(),Authorize.class);
-        RequiresDataAccess classDataAccess=AopUtils.findAnnotation(paramContext.getTarget().getClass(),RequiresDataAccess.class);
-        RequiresDataAccess methodDataAccess=AopUtils.findMethodAnnotation(paramContext.getTarget().getClass(),paramContext.getMethod(),RequiresDataAccess.class);
-
-        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);
-            return null;
-        }
-
-        if(methodAuth!=null&&methodAuth.ignore()){
-            cache.put(paramContext.getMethod(), EmptyAuthorizeDefinition.instance);
-            return null;
-        }
-
-
-        DefaultBasicAuthorizeDefinition authorizeDefinition=new DefaultBasicAuthorizeDefinition();
-
-        authorizeDefinition.put(classAuth);
-        authorizeDefinition.put(methodAuth);
-
-        authorizeDefinition.put(expression);
-
-        authorizeDefinition.put(classDataAccess);
-        authorizeDefinition.put(methodDataAccess);
-
-        cache.put(paramContext.getMethod(),authorizeDefinition);
-
-        return authorizeDefinition;
-    }
-
-}

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

@@ -121,7 +121,8 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
         this.user = user;
     }
 
-    void put(Authorize authorize) {
+    public void put(Authorize authorize) {
+        if (null == authorize || authorize.ignore()) return;
         permissions.addAll(Arrays.asList(authorize.permission()));
         actions.addAll(Arrays.asList(authorize.action()));
         roles.addAll(Arrays.asList(authorize.role()));
@@ -132,11 +133,13 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
         message = authorize.message();
     }
 
-    void put(RequiresExpression expression) {
+    public void put(RequiresExpression expression) {
+        if (null == expression) return;
         script = new DefaultScript(expression.language(), expression.value());
     }
 
-    void put(RequiresDataAccess dataAccess) {
+    public void put(RequiresDataAccess dataAccess) {
+        if (null == dataAccess) return;
         if (!dataAccess.permission().equals("")) {
             permissions.add(dataAccess.permission());
         }
@@ -148,7 +151,7 @@ public class DefaultBasicAuthorizeDefinition implements AuthorizeDefinition {
         } else if (DataAccessController.class != dataAccess.controllerClass()) {
             definition.setController(dataAccess.getClass().getName());
         }
-        dataAccessDefinition=definition;
+        dataAccessDefinition = definition;
     }
 
 

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

@@ -5,7 +5,7 @@ import org.hswebframework.web.authorization.define.AuthorizeDefinition;
 import org.hswebframework.web.boost.aop.context.MethodInterceptorParamContext;
 
 /**
- * Created by zhouhao on 2017/8/15.
+ * 权限控制上下文
  */
 public class AuthorizingContext {
     private AuthorizeDefinition definition;

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

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

+ 37 - 27
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java

@@ -27,7 +27,14 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
 
     private DataAccessController dataAccessController;
 
-    private Logger logger= LoggerFactory.getLogger(this.getClass());
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    public DefaultAuthorizingHandler(DataAccessController dataAccessController) {
+        this.dataAccessController = dataAccessController;
+    }
+
+    public DefaultAuthorizingHandler() {
+    }
 
     public void setDataAccessController(DataAccessController dataAccessController) {
         this.dataAccessController = dataAccessController;
@@ -36,29 +43,31 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
     @Override
     public void handle(AuthorizingContext context) {
 
-        handleRdac(context.getAuthentication(),context.getDefinition());
+        //进行rdac权限控制
+        handleRdac(context.getAuthentication(), context.getDefinition());
 
-        handleDataAccess(context.getAuthentication(),context.getDefinition(),context.getParamContext());
+        //进行数据权限控制
+        handleDataAccess(context.getAuthentication(), context.getDefinition(), context.getParamContext());
 
-        handleExpression(context.getAuthentication(),context.getDefinition(),context.getParamContext());
+        //表达式权限控制
+        handleExpression(context.getAuthentication(), context.getDefinition(), context.getParamContext());
 
     }
 
-    protected void handleDataAccess(Authentication authentication, AuthorizeDefinition definition, MethodInterceptorParamContext paramContext){
-
-        if(dataAccessController==null){
+    protected void handleDataAccess(Authentication authentication, AuthorizeDefinition definition, MethodInterceptorParamContext paramContext) {
+        if (dataAccessController == null) {
             logger.warn("dataAccessController is null,skip data access control!");
             return;
         }
-        List<Permission> permission=authentication.getPermissions()
+        List<Permission> permission = authentication.getPermissions()
                 .stream()
-                .filter(per->definition.getPermissions().contains(per.getId()))
+                .filter(per -> definition.getPermissions().contains(per.getId()))
                 .collect(Collectors.toList());
 
-        DataAccessController finalAccessController=dataAccessController;
+        DataAccessController finalAccessController = dataAccessController;
 
         //取得当前登录用户持有的控制规则
-        Set<DataAccessConfig> accesses =permission
+        Set<DataAccessConfig> accesses = permission
                 .stream().map(Permission::getDataAccesses)
                 .flatMap(Collection::stream)
                 .filter(access -> definition.getActions().contains(access.getAction()))
@@ -76,9 +85,10 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         }
 
     }
-    protected void handleExpression(Authentication authentication,AuthorizeDefinition definition, MethodInterceptorParamContext paramContext){
-        if(definition.getScript()!=null){
-            String scriptId= DigestUtils.md5Hex(definition.getScript().getScript());
+
+    protected void handleExpression(Authentication authentication, AuthorizeDefinition definition, MethodInterceptorParamContext paramContext) {
+        if (definition.getScript() != null) {
+            String scriptId = DigestUtils.md5Hex(definition.getScript().getScript());
 
             DynamicScriptEngine engine = DynamicScriptEngineFactory.getEngine(definition.getScript().getLanguage());
             if (null == engine) {
@@ -86,7 +96,7 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
             }
             if (!engine.compiled(scriptId)) {
                 try {
-                    engine.compile(scriptId,definition.getScript().getScript());
+                    engine.compile(scriptId, definition.getScript().getScript());
                 } catch (Exception e) {
                     logger.error("express compile error", e);
                     throw new AuthorizationException("{expression_error}");
@@ -101,20 +111,20 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         }
     }
 
-    protected void handleRdac(Authentication authentication,AuthorizeDefinition definition){
+    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();
-        Set<String> usersDef=definition.getUser();
+        Set<String> permissionsDef = definition.getPermissions();
+        Set<String> actionsDef = definition.getActions();
+        Set<String> rolesDef = definition.getRoles();
+        Set<String> usersDef = definition.getUser();
 
 
         // 控制权限
         if (!definition.getPermissions().isEmpty()) {
-            if(logger.isInfoEnabled()){
-                logger.info("do permission access handle : permissions{},actions{} ",permissionsDef,actionsDef);
+            if (logger.isInfoEnabled()) {
+                logger.info("do permission access handle : permissions{},actions{} ", permissionsDef, actionsDef);
             }
             List<Permission> permissions = authentication.getPermissions().stream()
                     .filter(permission -> {
@@ -126,7 +136,7 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
                         //判断action
                         List<String> actions = permission.getActions()
                                 .stream()
-                                .filter(rolesDef::contains)
+                                .filter(actionsDef::contains)
                                 .collect(Collectors.toList());
 
                         if (actions.isEmpty()) return false;
@@ -141,8 +151,8 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         }
         //控制角色
         if (!rolesDef.isEmpty()) {
-            if(logger.isInfoEnabled()){
-                logger.info("do role access handle : roles{} ",rolesDef);
+            if (logger.isInfoEnabled()) {
+                logger.info("do role access handle : roles{} ", rolesDef);
             }
             Function<Predicate<Role>, Boolean> func = logicalIsOr
                     ? authentication.getRoles().stream()::anyMatch
@@ -151,8 +161,8 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         }
         //控制用户
         if (!usersDef.isEmpty()) {
-            if(logger.isInfoEnabled()){
-                logger.info("do user access handle : users{} ",usersDef);
+            if (logger.isInfoEnabled()) {
+                logger.info("do user access handle : users{} ", usersDef);
             }
             Function<Predicate<String>, Boolean> func = logicalIsOr
                     ? usersDef.stream()::anyMatch

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

@@ -0,0 +1,44 @@
+/*
+ *  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.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;
+
+/**
+ * 当配置为自定义处理器时(实现{@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);
+    }
+}

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

@@ -0,0 +1,59 @@
+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 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.stream()
+                // 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;
+    }
+}

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

@@ -0,0 +1,86 @@
+package org.hswebframework.web.authorization.basic.handler.access;
+
+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;
+    }
+}

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

@@ -0,0 +1,114 @@
+package org.hswebframework.web.authorization.basic.handler.access;
+
+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;
+    }
+}

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

@@ -0,0 +1,129 @@
+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.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.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;
+    }
+}

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

@@ -0,0 +1,41 @@
+package org.hswebframework.web.authorization.basic.handler.access;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.hswebframework.expands.script.engine.DynamicScriptEngine;
+import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
+import org.hswebframework.utils.StringUtils;
+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;
+
+/**
+ * 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);
+        }
+    }
+
+}

+ 28 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/DefaultUserTokenParser.java

@@ -0,0 +1,28 @@
+package org.hswebframework.web.authorization.basic.web;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.util.function.Predicate;
+
+/**
+ * @author zhouhao
+ */
+public class DefaultUserTokenParser implements UserTokenParser {
+    @Override
+    public String parseToken(HttpServletRequest request, Predicate<String> tokenValidate) {
+        String token = request.getParameter("access_token");
+        if (null != token) {
+            if (tokenValidate.test(token))
+                return token;
+        }
+
+        HttpSession session = request.getSession(false);
+
+        if (session != null) {
+            if (tokenValidate.test(session.getId()))
+                return session.getId();
+        }
+
+        return null;
+    }
+}

+ 49 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignIn.java

@@ -0,0 +1,49 @@
+package org.hswebframework.web.authorization.basic.web;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.hswebframework.web.WebUtil;
+import org.hswebframework.web.authorization.listener.AuthorizationListener;
+import org.hswebframework.web.authorization.listener.event.AuthorizationSuccessEvent;
+import org.hswebframework.web.authorization.token.UserToken;
+import org.hswebframework.web.authorization.token.UserTokenManager;
+
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class UserOnSignIn implements AuthorizationListener<AuthorizationSuccessEvent> {
+    private UserTokenManager userTokenManager;
+
+    public UserOnSignIn(UserTokenManager userTokenManager) {
+        this.userTokenManager = userTokenManager;
+    }
+    @Override
+    public void on(AuthorizationSuccessEvent event) {
+        UserToken token = UserTokenHolder.currentToken();
+        String tokenType = (String) event.getParameter("token_type").orElse("sessionId");
+
+        if (token != null) {
+            userTokenManager.signOutByToken(token.getToken());
+        }
+        token = userTokenManager.signIn(createToken(tokenType), event.getAuthentication().getUser().getId());
+        event.getResult().put("token", token.getToken());
+
+    }
+
+    protected String createToken(String type) {
+        switch (type) {
+            case "simple":
+                return DigestUtils.md5Hex(UUID.randomUUID().toString().concat(String.valueOf(Math.random())));
+            default:
+                return Optional.ofNullable(WebUtil.getHttpServletRequest())
+                        .orElseThrow(UnsupportedOperationException::new)
+                        .getSession()
+                        .getId();
+        }
+
+    }
+}

+ 31 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserOnSignOut.java

@@ -0,0 +1,31 @@
+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;
+import org.hswebframework.web.authorization.token.UserTokenManager;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class UserOnSignOut implements AuthorizationListener<AuthorizationExitEvent> {
+    private UserTokenManager userTokenManager;
+
+    public UserOnSignOut(UserTokenManager userTokenManager) {
+        this.userTokenManager = userTokenManager;
+    }
+
+    @Override
+    public void on(AuthorizationExitEvent event) {
+        userTokenManager.signOutByToken(geToken());
+    }
+
+    protected String geToken() {
+        // TODO: 17-8-16 更多创建方式
+        return ThreadLocalUtils.<UserToken>get(UserToken.class.getName()).getToken();
+    }
+}

+ 36 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenAuthenticationSupplier.java

@@ -0,0 +1,36 @@
+package org.hswebframework.web.authorization.basic.web;
+
+import org.hswebframework.web.ThreadLocalUtils;
+import org.hswebframework.web.authorization.Authentication;
+import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.AuthenticationSupplier;
+import org.hswebframework.web.authorization.token.UserToken;
+
+import java.util.Optional;
+
+/**
+ * @author zhouhao
+ */
+public class UserTokenAuthenticationSupplier implements AuthenticationSupplier {
+
+    private AuthenticationManager authenticationManager;
+
+    public UserTokenAuthenticationSupplier(AuthenticationManager authenticationManager) {
+        this.authenticationManager = authenticationManager;
+    }
+
+    @Override
+    public Authentication get(String userId) {
+        if (userId == null) return null;
+        return authenticationManager.getByUserId(userId);
+    }
+
+    protected UserToken getCurrentUserToken() {
+        return UserTokenHolder.currentToken();
+    }
+
+    @Override
+    public Authentication get() {
+        return ThreadLocalUtils.get(Authentication.class.getName(), () -> get(Optional.ofNullable(getCurrentUserToken()).map(UserToken::getUserId).orElse(null)));
+    }
+}

+ 25 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenHolder.java

@@ -0,0 +1,25 @@
+package org.hswebframework.web.authorization.basic.web;
+
+import org.hswebframework.web.ThreadLocalUtils;
+import org.hswebframework.web.authorization.token.UserToken;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public final class UserTokenHolder {
+
+    private UserTokenHolder() {
+    }
+
+    public static UserToken currentToken() {
+        return ThreadLocalUtils.get(UserToken.class.getName());
+    }
+
+    public static UserToken setCurrent(UserToken token) {
+        ThreadLocalUtils.put(UserToken.class.getName(), token);
+        return token;
+    }
+
+}

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

@@ -0,0 +1,13 @@
+package org.hswebframework.web.authorization.basic.web;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.function.Predicate;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface UserTokenParser {
+    String parseToken(HttpServletRequest request, Predicate<String> tokenValidate);
+}

+ 47 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/WebUserTokenInterceptor.java

@@ -0,0 +1,47 @@
+package org.hswebframework.web.authorization.basic.web;
+
+import org.hswebframework.web.authorization.token.UserToken;
+import org.hswebframework.web.authorization.token.UserTokenManager;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class WebUserTokenInterceptor extends HandlerInterceptorAdapter {
+
+    private UserTokenManager userTokenManager;
+
+    private UserTokenParser userTokenParser;
+
+    public WebUserTokenInterceptor(UserTokenManager userTokenManager, UserTokenParser userTokenParser) {
+        this.userTokenManager = userTokenManager;
+        this.userTokenParser = userTokenParser;
+    }
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        String token = userTokenParser.parseToken(request, userTokenManager::tokenIsLoggedIn);
+        if (null == token) {
+            return true;
+        }
+        userTokenManager.touch(token);
+        UserToken userToken = userTokenManager.getByToken(token);
+        if (userToken == null) {
+            return true;
+        } else if (userToken.isEffective()) {
+            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;
+    }
+}

+ 7 - 1
hsweb-examples/hsweb-examples-simple/pom.xml

@@ -109,9 +109,15 @@
             <version>${project.version}</version>
         </dependency>
         <!--使用shiro实现权限控制-->
+        <!--<dependency>-->
+            <!--<groupId>org.hswebframework.web</groupId>-->
+            <!--<artifactId>hsweb-authorization-shiro</artifactId>-->
+            <!--<version>${project.version}</version>-->
+        <!--</dependency>-->
+        <!--使用基础权限控制-->
         <dependency>
             <groupId>org.hswebframework.web</groupId>
-            <artifactId>hsweb-authorization-shiro</artifactId>
+            <artifactId>hsweb-authorization-basic</artifactId>
             <version>${project.version}</version>
         </dependency>
 

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

@@ -21,6 +21,7 @@ import com.alibaba.fastjson.JSON;
 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.simple.SimpleFieldFilterDataAccessConfig;
 import org.hswebframework.web.commons.entity.DataStatus;
 import org.hswebframework.web.commons.entity.factory.EntityFactory;
@@ -76,6 +77,7 @@ import java.util.stream.Stream;
 @EnableCaching
 @EnableAspectJAutoProxy
 @EnableAccessLogger
+@EnableAopAuthorize
 public class SpringBootExample
         implements CommandLineRunner {
 

+ 0 - 1
hsweb-system/hsweb-system-organizational/hsweb-system-organizational-authorization/src/main/java/org/hswebframework/web/organizational/authorization/PersonnelAuthorization.java

@@ -84,7 +84,6 @@ public interface PersonnelAuthorization extends Serializable {
     /**
      * @return 根地区ID
      */
-    @Deprecated
     default Set<String> getRootDistrictId() {
         return getDistrictIds().stream().map(TreeNode::getValue).collect(Collectors.toSet());
     }

+ 2 - 2
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

@@ -245,8 +245,8 @@ public class SimplePersonService extends EnableCacheGenericEntityService<PersonE
         PersonEntity entity = selectByPk(personId);
         assertNotNull(entity);
 
-        Personnel personnel = entityFactory.newInstance(Personnel.class, SimplePersonnel.class);
-        entityFactory.copyProperties(entity, personnel);
+        Personnel personnel = entityFactory.newInstance(Personnel.class, SimplePersonnel.class, entity);
+
         authorization.setPersonnel(personnel);
 
         // 获取用户的职位ID集合(多个职位)