瀏覽代碼

增加部分实现

zhou-hao 5 年之前
父節點
當前提交
8ce58b3bec
共有 53 個文件被更改,包括 1082 次插入431 次删除
  1. 3 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationHolder.java
  2. 3 6
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationManager.java
  3. 4 2
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationSupplier.java
  4. 1 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationInitializeService.java
  5. 48 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/ReactiveAuthenticationManager.java
  6. 1 9
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessConfig.java
  7. 0 28
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/ScriptDataAccessConfig.java
  8. 4 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/builder/DataAccessConfigBuilder.java
  9. 14 6
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/DefaultAuthorizationAutoConfiguration.java
  10. 3 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleAuthentication.java
  11. 0 21
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleScriptDataAccessConfig.java
  12. 15 5
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/builder/SimpleDataAccessConfigBuilder.java
  13. 0 3
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/builder/SimpleDataAccessConfigBuilderFactory.java
  14. 3 1
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/ThirdPartAuthenticationManager.java
  15. 25 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/ThirdPartReactiveAuthenticationManager.java
  16. 77 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenAuthenticationSupplier.java
  17. 10 9
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenReactiveAuthenticationSupplier.java
  18. 1 1
      hsweb-authorization/hsweb-authorization-api/src/test/java/org/hswebframework/web/authorization/AuthenticationTests.java
  19. 13 8
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java
  20. 2 2
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/BasicAuthorizationTokenParser.java
  21. 112 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationInfo.java
  22. 10 60
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationManager.java
  23. 62 69
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationProperties.java
  24. 35 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedReactiveAuthenticationManager.java
  25. 0 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/DefaultDataAccessController.java
  26. 0 41
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/access/ScriptDataAccessHandler.java
  27. 2 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/AuthorizationController.java
  28. 4 3
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenController.java
  29. 2 30
      hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/TestApplication.java
  30. 0 65
      hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/WebFluxTests.java
  31. 2 1
      hsweb-authorization/hsweb-authorization-basic/src/test/resources/application.yml
  32. 1 0
      hsweb-commons/hsweb-commons-api/pom.xml
  33. 17 7
      hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EasyormRepositoryRegistrar.java
  34. 49 0
      hsweb-core/src/main/java/org/hswebframework/web/event/GenericsPayloadApplicationEvent.java
  35. 4 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/ActionEntity.java
  36. 8 5
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/AuthorizationSettingEntity.java
  37. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/DataAccessEntity.java
  38. 6 3
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/PermissionEntity.java
  39. 18 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/pom.xml
  40. 50 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationServiceAutoConfiguration.java
  41. 28 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationWebAutoConfiguration.java
  42. 137 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/DefaultReactiveAuthenticationInitializeService.java
  43. 54 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/DefaultReactiveAuthenticationManager.java
  44. 72 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/webflux/WebFluxPermissionController.java
  45. 14 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/webflux/WebFluxUserController.java
  46. 4 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/resources/META-INF/spring.factories
  47. 96 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/test/java/org/hswebframework/web/system/authorization/defaults/service/reactive/DefaultReactiveAuthenticationManagerTest.java
  48. 3 6
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/test/java/org/hswebframework/web/system/authorization/defaults/service/reactive/ReactiveTestApplication.java
  49. 59 0
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/test/java/org/hswebframework/web/system/authorization/defaults/service/reactive/WebFluxPermissionControllerTest.java
  50. 0 15
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/pom.xml
  51. 0 15
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/pom.xml
  52. 0 2
      hsweb-system/hsweb-system-authorization/pom.xml
  53. 5 1
      pom.xml

+ 3 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationHolder.java

@@ -49,9 +49,11 @@ public final class AuthenticationHolder {
 
     private static final ReadWriteLock lock = new ReentrantReadWriteLock();
 
-    private static Optional<Authentication> get(Function<AuthenticationSupplier, Authentication> function) {
+    private static Optional<Authentication> get(Function<AuthenticationSupplier, Optional<Authentication>> function) {
 
         return Flux.fromStream(suppliers.stream().map(function))
+                .filter(Optional::isPresent)
+                .map(Optional::get)
                 .reduceWith(CompositeAuthentication::new, CompositeAuthentication::merge)
                 .filter(CompositeAuthentication::isNotEmpty)
                 .map(Authentication.class::cast)

+ 3 - 6
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationManager.java

@@ -18,10 +18,7 @@
 
 package org.hswebframework.web.authorization;
 
-import reactor.core.publisher.Mono;
-
-import java.io.Serializable;
-import java.util.Map;
+import java.util.Optional;
 
 /**
  * 授权信息管理器,用于获取用户授权和同步授权信息
@@ -37,7 +34,7 @@ public interface AuthenticationManager {
      * @param request 授权请求
      * @return 授权成功则返回用户权限信息
      */
-    Mono<Authentication> authenticate(Mono<AuthenticationRequest> request);
+    Authentication authenticate(AuthenticationRequest request);
 
     /**
      * 根据用户ID获取权限信息
@@ -45,7 +42,7 @@ public interface AuthenticationManager {
      * @param userId 用户ID
      * @return 权限信息
      */
-    Mono<Authentication> getByUserId(String userId);
+    Optional<Authentication> getByUserId(String userId);
 
 
 }

+ 4 - 2
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationSupplier.java

@@ -19,6 +19,7 @@ package org.hswebframework.web.authorization;
 
 import reactor.core.publisher.Mono;
 
+import java.util.Optional;
 import java.util.function.Supplier;
 
 /**
@@ -27,6 +28,7 @@ import java.util.function.Supplier;
  * @see Authentication
  * @see ReactiveAuthenticationHolder
  */
-public interface AuthenticationSupplier extends Supplier<Authentication> {
-    Authentication get(String userId);
+public interface AuthenticationSupplier extends Supplier<Optional<Authentication>> {
+
+    Optional<Authentication> get(String userId);
 }

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationInitializeService.java

@@ -27,7 +27,7 @@ import reactor.core.publisher.Mono;
  * @author zhouhao
  * @since 4.0
  */
-public interface AuthenticationInitializeService {
+public interface ReactiveAuthenticationInitializeService {
     /**
      * 根据用户ID初始化权限信息
      *

+ 48 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/ReactiveAuthenticationManager.java

@@ -0,0 +1,48 @@
+/*
+ *  Copyright 2019 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;
+
+import reactor.core.publisher.Mono;
+
+/**
+ * 授权信息管理器,用于获取用户授权和同步授权信息
+ *
+ * @author zhouhao
+ * @see 3.0
+ */
+public interface ReactiveAuthenticationManager {
+
+    /**
+     * 进行授权操作
+     *
+     * @param request 授权请求
+     * @return 授权成功则返回用户权限信息
+     */
+    Mono<Authentication> authenticate(Mono<AuthenticationRequest> request);
+
+    /**
+     * 根据用户ID获取权限信息
+     *
+     * @param userId 用户ID
+     * @return 权限信息
+     */
+    Mono<Authentication> getByUserId(String userId);
+
+
+}

+ 1 - 9
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/DataAccessConfig.java

@@ -30,7 +30,6 @@ import java.io.Serializable;
  * @author zhouhao
  * @see CustomDataAccessConfig
  * @see OwnCreatedDataAccessConfig
- * @see ScriptDataAccessConfig
  */
 public interface DataAccessConfig extends Serializable {
 
@@ -72,19 +71,12 @@ public interface DataAccessConfig extends Serializable {
         String FIELD_SCOPE = "FIELD_SCOPE";
 
         /**
-         * 字段过滤,黑名单
+         * 禁止操作字段
          *
          * @see FieldFilterDataAccessConfig#getType()
          */
         String DENY_FIELDS = "DENY_FIELDS";
 
-        /**
-         * 自定义脚本方式
-         *
-         * @see ScriptDataAccessConfig#getType()
-         */
-        String SCRIPT = "SCRIPT";
-
         /**
          * 自定义控制器
          *

+ 0 - 28
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/access/ScriptDataAccessConfig.java

@@ -1,28 +0,0 @@
-package org.hswebframework.web.authorization.access;
-
-/**
- * 通过脚本来控制数据操作权限.脚本可以在前端设置角色的时候进行编辑
- *
- * @author zhouhao
- */
-public interface ScriptDataAccessConfig extends DataAccessConfig {
-    @Override
-    default String getType() {
-        return DefaultType.SCRIPT;
-    }
-
-    /**
-     * 脚本语言: javascript(js),groovy
-     *
-     * @return 语言
-     */
-    String getScriptLanguage();
-
-    /**
-     * 脚本内容,在进行验证的时候会执行脚本
-     *
-     * @return 脚本
-     */
-    String getScript();
-
-}

+ 4 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/builder/DataAccessConfigBuilder.java

@@ -2,6 +2,8 @@ package org.hswebframework.web.authorization.builder;
 
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 
+import java.util.Map;
+
 /**
  *
  * @author zhouhao
@@ -9,5 +11,7 @@ import org.hswebframework.web.authorization.access.DataAccessConfig;
 public interface DataAccessConfigBuilder {
     DataAccessConfigBuilder fromJson(String json);
 
+    DataAccessConfigBuilder fromMap(Map<String,Object> json);
+
     DataAccessConfig build();
 }

+ 14 - 6
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/DefaultAuthorizationAutoConfiguration.java

@@ -1,14 +1,13 @@
 package org.hswebframework.web.authorization.simple;
 
-import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.ReactiveAuthenticationHolder;
-import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.*;
 import org.hswebframework.web.authorization.builder.AuthenticationBuilderFactory;
 import org.hswebframework.web.authorization.builder.DataAccessConfigBuilderFactory;
 import org.hswebframework.web.authorization.simple.builder.DataAccessConfigConvert;
 import org.hswebframework.web.authorization.simple.builder.SimpleAuthenticationBuilderFactory;
 import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
 import org.hswebframework.web.authorization.token.DefaultUserTokenManager;
+import org.hswebframework.web.authorization.token.UserTokenAuthenticationSupplier;
 import org.hswebframework.web.authorization.token.UserTokenReactiveAuthenticationSupplier;
 import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.hswebframework.web.authorization.twofactor.TwoFactorValidatorManager;
@@ -40,14 +39,23 @@ public class DefaultAuthorizationAutoConfiguration {
     }
 
     @Bean
-    @ConditionalOnBean(AuthenticationManager.class)
-    public UserTokenReactiveAuthenticationSupplier userTokenAuthenticationSupplier(UserTokenManager userTokenManager,
-                                                                                   AuthenticationManager authenticationManager) {
+    @ConditionalOnBean(ReactiveAuthenticationManager.class)
+    public UserTokenReactiveAuthenticationSupplier userTokenReactiveAuthenticationSupplier(UserTokenManager userTokenManager,
+                                                                                   ReactiveAuthenticationManager authenticationManager) {
         UserTokenReactiveAuthenticationSupplier supplier = new UserTokenReactiveAuthenticationSupplier(userTokenManager, authenticationManager);
         ReactiveAuthenticationHolder.addSupplier(supplier);
         return supplier;
     }
 
+    @Bean
+    @ConditionalOnBean(AuthenticationManager.class)
+    public UserTokenAuthenticationSupplier userTokenAuthenticationSupplier(UserTokenManager userTokenManager,
+                                                                           AuthenticationManager authenticationManager) {
+        UserTokenAuthenticationSupplier supplier = new UserTokenAuthenticationSupplier(userTokenManager, authenticationManager);
+        AuthenticationHolder.addSupplier(supplier);
+        return supplier;
+    }
+
     @Bean
     @ConditionalOnMissingBean(DataAccessConfigBuilderFactory.class)
     @ConfigurationProperties(prefix = "hsweb.authorization.data-access", ignoreInvalidFields = true)

+ 3 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleAuthentication.java

@@ -58,6 +58,9 @@ public class SimpleAuthentication implements Authentication {
 
     @Override
     public List<Permission> getPermissions() {
+        if(permissions==null){
+            return Collections.emptyList();
+        }
         return new ArrayList<>(permissions);
     }
 

+ 0 - 21
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/SimpleScriptDataAccessConfig.java

@@ -1,21 +0,0 @@
-package org.hswebframework.web.authorization.simple;
-
-import lombok.*;
-import org.hswebframework.web.authorization.access.ScriptDataAccessConfig;
-
-/**
- * @author zhouhao
- */
-@Getter
-@Setter
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class SimpleScriptDataAccessConfig extends AbstractDataAccessConfig implements ScriptDataAccessConfig {
-
-    private static final long serialVersionUID = 2667127339980983720L;
-
-    private String script;
-
-    private String scriptLanguage;
-}

+ 15 - 5
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/builder/SimpleDataAccessConfigBuilder.java

@@ -5,17 +5,21 @@ import com.alibaba.fastjson.JSONObject;
 import org.hswebframework.web.authorization.access.DataAccessConfig;
 import org.hswebframework.web.authorization.builder.DataAccessConfigBuilder;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
 /**
  * @author zhouhao
  */
 public class SimpleDataAccessConfigBuilder implements DataAccessConfigBuilder {
-    private String json;
 
     private List<DataAccessConfigConvert> converts;
 
+    private Map<String, Object> config = new HashMap<>();
+
+
     public SimpleDataAccessConfigBuilder(List<DataAccessConfigConvert> converts) {
         Objects.requireNonNull(converts);
         this.converts = converts;
@@ -23,14 +27,20 @@ public class SimpleDataAccessConfigBuilder implements DataAccessConfigBuilder {
 
     @Override
     public DataAccessConfigBuilder fromJson(String json) {
-        this.json = json;
+        config.putAll(JSON.parseObject(json));
+        return this;
+    }
+
+    @Override
+    public DataAccessConfigBuilder fromMap(Map<String, Object> map) {
+        config.putAll(map);
         return this;
     }
 
     @Override
     public DataAccessConfig build() {
-        Objects.requireNonNull(json);
-        JSONObject jsonObject = JSON.parseObject(json);
+        Objects.requireNonNull(config);
+        JSONObject jsonObject = new JSONObject(config);
 
         String type = jsonObject.getString("type");
         String action = jsonObject.getString("action");
@@ -40,7 +50,7 @@ public class SimpleDataAccessConfigBuilder implements DataAccessConfigBuilder {
         Objects.requireNonNull(action);
 
         if (config == null) {
-            config = json;
+            config = jsonObject.toJSONString();
         }
         String finalConfig = config;
 

+ 0 - 3
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/builder/SimpleDataAccessConfigBuilderFactory.java

@@ -81,9 +81,6 @@ public class SimpleDataAccessConfigBuilderFactory implements DataAccessConfigBui
             converts.add(createConfig(OWN_CREATED, (action, config) -> new SimpleOwnCreatedDataAccessConfig(action)));
         }
 
-        if (defaultSupportConvert.contains(SCRIPT)) {
-            converts.add(createJsonConfig(SCRIPT, SimpleScriptDataAccessConfig.class));
-        }
 
         if (defaultSupportConvert.contains(CUSTOM)) {
             converts.add(createConfig(CUSTOM, (action, config) -> new SimpleCustomDataAccessConfigConfig(config)));

+ 3 - 1
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/ThirdPartAuthenticationManager.java

@@ -3,6 +3,8 @@ package org.hswebframework.web.authorization.token;
 import org.hswebframework.web.authorization.Authentication;
 import reactor.core.publisher.Mono;
 
+import java.util.Optional;
+
 /**
  * @author zhouhao
  * @since 1.0
@@ -20,6 +22,6 @@ public interface ThirdPartAuthenticationManager {
      * @param userId 用户ID
      * @return 权限信息
      */
-    Mono<Authentication> getByUserId(String userId);
+    Optional<Authentication> getByUserId(String userId);
 
 }

+ 25 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/ThirdPartReactiveAuthenticationManager.java

@@ -0,0 +1,25 @@
+package org.hswebframework.web.authorization.token;
+
+import org.hswebframework.web.authorization.Authentication;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author zhouhao
+ * @since 1.0
+ */
+public interface ThirdPartReactiveAuthenticationManager {
+
+    /**
+     * @return 支持的tokenType
+     */
+    String getTokenType();
+
+    /**
+     * 根据用户ID获取权限信息
+     *
+     * @param userId 用户ID
+     * @return 权限信息
+     */
+    Mono<Authentication> getByUserId(String userId);
+
+}

+ 77 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenAuthenticationSupplier.java

@@ -0,0 +1,77 @@
+package org.hswebframework.web.authorization.token;
+
+import org.hswebframework.web.authorization.*;
+import org.hswebframework.web.context.ContextKey;
+import org.hswebframework.web.context.ContextUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import reactor.core.publisher.Mono;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * @author zhouhao
+ */
+public class UserTokenAuthenticationSupplier implements AuthenticationSupplier {
+
+    private AuthenticationManager defaultAuthenticationManager;
+
+    private UserTokenManager userTokenManager;
+
+    private Map<String, ThirdPartAuthenticationManager> thirdPartAuthenticationManager = new HashMap<>();
+
+    public UserTokenAuthenticationSupplier(UserTokenManager userTokenManager, AuthenticationManager defaultAuthenticationManager) {
+        this.defaultAuthenticationManager = defaultAuthenticationManager;
+        this.userTokenManager = userTokenManager;
+    }
+
+    @Autowired(required = false)
+    public void setThirdPartAuthenticationManager(List<ThirdPartAuthenticationManager> thirdPartReactiveAuthenticationManager) {
+        for (ThirdPartAuthenticationManager manager : thirdPartReactiveAuthenticationManager) {
+            this.thirdPartAuthenticationManager.put(manager.getTokenType(), manager);
+        }
+    }
+
+    @Override
+    public Optional<Authentication> get(String userId) {
+        if (userId == null) {
+            return Optional.empty();
+        }
+        return get(this.defaultAuthenticationManager, userId);
+    }
+
+    protected Optional<Authentication> get(ThirdPartAuthenticationManager authenticationManager, String userId) {
+        if (null == userId) {
+            return Optional.empty();
+        }
+        if (null == authenticationManager) {
+            return this.defaultAuthenticationManager.getByUserId(userId);
+        }
+        return authenticationManager.getByUserId(userId);
+    }
+
+    protected Optional<Authentication> get(AuthenticationManager authenticationManager, String userId) {
+        if (null == userId) {
+            return Optional.empty();
+        }
+        if (null == authenticationManager) {
+            authenticationManager = this.defaultAuthenticationManager;
+        }
+        return authenticationManager.getByUserId(userId);
+    }
+
+    @Override
+    public Optional<Authentication> get() {
+
+        return ContextUtils.currentContext()
+                .get(ContextKey.of(ParsedToken.class))
+                .map(t -> userTokenManager.getByToken(t.getToken()))
+                .map(tokenMono -> tokenMono
+                        .map(token -> get(thirdPartAuthenticationManager.get(token.getType()), token.getUserId()))
+                        .flatMap(Mono::justOrEmpty))
+                .flatMap(Mono::blockOptional);
+
+    }
+}

+ 10 - 9
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/token/UserTokenReactiveAuthenticationSupplier.java

@@ -1,7 +1,7 @@
 package org.hswebframework.web.authorization.token;
 
 import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
 import org.hswebframework.web.authorization.ReactiveAuthenticationSupplier;
 import org.hswebframework.web.context.ContextKey;
 import org.hswebframework.web.context.ContextUtils;
@@ -17,20 +17,20 @@ import java.util.Map;
  */
 public class UserTokenReactiveAuthenticationSupplier implements ReactiveAuthenticationSupplier {
 
-    private AuthenticationManager defaultAuthenticationManager;
+    private ReactiveAuthenticationManager defaultAuthenticationManager;
 
     private UserTokenManager userTokenManager;
 
-    private Map<String, ThirdPartAuthenticationManager> thirdPartAuthenticationManager = new HashMap<>();
+    private Map<String, ThirdPartReactiveAuthenticationManager> thirdPartAuthenticationManager = new HashMap<>();
 
-    public UserTokenReactiveAuthenticationSupplier(UserTokenManager userTokenManager, AuthenticationManager defaultAuthenticationManager) {
+    public UserTokenReactiveAuthenticationSupplier(UserTokenManager userTokenManager, ReactiveAuthenticationManager defaultAuthenticationManager) {
         this.defaultAuthenticationManager = defaultAuthenticationManager;
         this.userTokenManager=userTokenManager;
     }
 
     @Autowired(required = false)
-    public void setThirdPartAuthenticationManager(List<ThirdPartAuthenticationManager> thirdPartAuthenticationManager) {
-        for (ThirdPartAuthenticationManager manager : thirdPartAuthenticationManager) {
+    public void setThirdPartAuthenticationManager(List<ThirdPartReactiveAuthenticationManager> thirdPartReactiveAuthenticationManager) {
+        for (ThirdPartReactiveAuthenticationManager manager : thirdPartReactiveAuthenticationManager) {
             this.thirdPartAuthenticationManager.put(manager.getTokenType(), manager);
         }
     }
@@ -43,7 +43,7 @@ public class UserTokenReactiveAuthenticationSupplier implements ReactiveAuthenti
         return get(this.defaultAuthenticationManager, userId);
     }
 
-    protected Mono<Authentication> get(ThirdPartAuthenticationManager authenticationManager, String userId) {
+    protected Mono<Authentication> get(ThirdPartReactiveAuthenticationManager authenticationManager, String userId) {
         if (null == userId) {
             return null;
         }
@@ -53,7 +53,7 @@ public class UserTokenReactiveAuthenticationSupplier implements ReactiveAuthenti
         return authenticationManager.getByUserId(userId);
     }
 
-    protected Mono<Authentication> get(AuthenticationManager authenticationManager, String userId) {
+    protected Mono<Authentication> get(ReactiveAuthenticationManager authenticationManager, String userId) {
         if (null == userId) {
             return null;
         }
@@ -69,7 +69,8 @@ public class UserTokenReactiveAuthenticationSupplier implements ReactiveAuthenti
                 .flatMap(context ->
                         context.get(ContextKey.of(ParsedToken.class))
                                 .map(t -> userTokenManager.getByToken(t.getToken()))
-                                .map(tokenMono -> tokenMono.flatMap(token -> get(thirdPartAuthenticationManager.get(token.getType()), token.getUserId())))
+                                .map(tokenMono -> tokenMono
+                                        .flatMap(token -> get(thirdPartAuthenticationManager.get(token.getType()), token.getUserId())))
                                 .orElseGet(Mono::empty));
 
     }

+ 1 - 1
hsweb-authorization/hsweb-authorization-api/src/test/java/org/hswebframework/web/authorization/AuthenticationTests.java

@@ -96,7 +96,7 @@ public class AuthenticationTests {
                 .build();
 
         //初始化权限管理器,用于获取用户的权限信息
-        AuthenticationManager authenticationManager = new AuthenticationManager() {
+        ReactiveAuthenticationManager authenticationManager = new ReactiveAuthenticationManager() {
             @Override
             public Mono<Authentication> authenticate(Mono<AuthenticationRequest> request) {
                 return Mono.empty();

+ 13 - 8
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java

@@ -1,10 +1,12 @@
 package org.hswebframework.web.authorization.basic.configuration;
 
 import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
 import org.hswebframework.web.authorization.access.DataAccessController;
 import org.hswebframework.web.authorization.access.DataAccessHandler;
 import org.hswebframework.web.authorization.basic.aop.AopMethodAuthorizeDefinitionParser;
-import org.hswebframework.web.authorization.basic.embed.EmbedAuthenticationManager;
+import org.hswebframework.web.authorization.basic.embed.EmbedAuthenticationProperties;
+import org.hswebframework.web.authorization.basic.embed.EmbedReactiveAuthenticationManager;
 import org.hswebframework.web.authorization.basic.handler.DefaultAuthorizingHandler;
 import org.hswebframework.web.authorization.basic.handler.UserAllowPermissionHandler;
 import org.hswebframework.web.authorization.basic.handler.access.DefaultDataAccessController;
@@ -16,6 +18,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.boot.autoconfigure.condition.*;
 import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.Ordered;
@@ -33,6 +36,7 @@ import java.util.List;
  * @since 3.0
  */
 @Configuration
+@EnableConfigurationProperties(EmbedAuthenticationProperties.class)
 public class AuthorizingHandlerAutoConfiguration {
 
     @Bean
@@ -85,19 +89,19 @@ public class AuthorizingHandlerAutoConfiguration {
                                                               AopMethodAuthorizeDefinitionParser parser,
                                                               List<UserTokenParser> userTokenParser) {
 
-        return new WebMvcConfigurerAdapter() {
+        return new WebMvcConfigurer() {
             @Override
             public void addInterceptors(InterceptorRegistry registry) {
                 registry.addInterceptor(new WebUserTokenInterceptor(userTokenManager, userTokenParser, parser));
-                super.addInterceptors(registry);
+
             }
         };
     }
 
     @Bean
-    @ConditionalOnMissingBean(AuthenticationManager.class)
-    public AuthenticationManager embedAuthenticationManager() {
-        return new EmbedAuthenticationManager();
+    @ConditionalOnMissingBean(ReactiveAuthenticationManager.class)
+    public ReactiveAuthenticationManager embedAuthenticationManager(EmbedAuthenticationProperties properties) {
+        return new EmbedReactiveAuthenticationManager(properties);
     }
 
     @Bean
@@ -130,8 +134,9 @@ public class AuthorizingHandlerAutoConfiguration {
     }
 
     @Bean
-    public UserTokenController userTokenController() {
-        return new UserTokenController();
+    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
+    public ReactiveUserTokenController userTokenController() {
+        return new ReactiveUserTokenController();
     }
 
     @Configuration

+ 2 - 2
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/BasicAuthorizationTokenParser.java

@@ -60,8 +60,8 @@ public class BasicAuthorizationTokenParser implements UserTokenForTypeParser {
             if (usernameAndPassword.contains(":")) {
                 String[] arr = usernameAndPassword.split("[:]");
                 Authentication authentication = authenticationManager
-                        .authenticate(Mono.just(new PlainTextUsernamePasswordAuthenticationRequest(arr[0], arr[1])))
-                        .blockOptional().orElse(null);
+                        .authenticate(new PlainTextUsernamePasswordAuthenticationRequest(arr[0], arr[1]))
+                        ;
                 if (authentication != null) {
                     return new AuthorizedToken() {
                         @Override

+ 112 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationInfo.java

@@ -0,0 +1,112 @@
+package org.hswebframework.web.authorization.basic.embed;
+
+import com.alibaba.fastjson.JSON;
+import lombok.Getter;
+import lombok.Setter;
+import org.hswebframework.web.authorization.Authentication;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.builder.DataAccessConfigBuilderFactory;
+import org.hswebframework.web.authorization.simple.SimpleAuthentication;
+import org.hswebframework.web.authorization.simple.SimplePermission;
+import org.hswebframework.web.authorization.simple.SimpleRole;
+import org.hswebframework.web.authorization.simple.SimpleUser;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <pre>
+ * hsweb:
+ *      users:
+ *          admin:
+ *            name: 超级管理员
+ *            username: admin
+ *            password: admin
+ *            roles:
+ *              - id: admin
+ *                name: 管理员
+ *              - id: user
+ *                name: 用户
+ *            permissions:
+ *              - id: user-manager
+ *                actions: *
+ *                dataAccesses:
+ *                  - action: query
+ *                    type: DENY_FIELDS
+ *                    fields: password,salt
+ * </pre>
+ *
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+@Getter
+@Setter
+public class EmbedAuthenticationInfo {
+
+    private String id;
+
+    private String name;
+
+    private String username;
+
+    private String type;
+
+    private String password;
+
+    private List<SimpleRole> roles = new ArrayList<>();
+
+    private List<PermissionInfo> permissions = new ArrayList<>();
+
+    private Map<String, List<String>> permissionsSimple = new HashMap<>();
+
+    @Getter
+    @Setter
+    public static class PermissionInfo {
+        private String id;
+
+        private String name;
+
+        private Set<String> actions = new HashSet<>();
+
+        private List<Map<String, Object>> dataAccesses = new ArrayList<>();
+    }
+
+    public Authentication toAuthentication(DataAccessConfigBuilderFactory factory) {
+        SimpleAuthentication authentication = new SimpleAuthentication();
+        SimpleUser user = new SimpleUser();
+        user.setId(id);
+        user.setName(name);
+        user.setUsername(username);
+        user.setType(type);
+        authentication.setUser(user);
+        authentication.setRoles((List) roles);
+        List<Permission> permissionList = new ArrayList<>();
+
+        permissionList.addAll(permissions.stream()
+                .map(info -> {
+                    SimplePermission permission = new SimplePermission();
+                    permission.setId(info.getId());
+                    permission.setName(info.getName());
+                    permission.setActions(info.getActions());
+                    permission.setDataAccesses(info.getDataAccesses()
+                            .stream().map(conf -> factory.create()
+                                    .fromMap(conf)
+                                    .build()).collect(Collectors.toSet()));
+                    return permission;
+
+                })
+                .collect(Collectors.toList()));
+
+        permissionList.addAll(permissionsSimple.entrySet().stream()
+                .map(entry -> {
+                    SimplePermission permission = new SimplePermission();
+                    permission.setId(entry.getKey());
+                    permission.setActions(new HashSet<>(entry.getValue()));
+                    return permission;
+                }).collect(Collectors.toList()));
+
+        authentication.setPermissions(permissionList);
+        return authentication;
+    }
+
+}

+ 10 - 60
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationManager.java

@@ -1,87 +1,37 @@
 package org.hswebframework.web.authorization.basic.embed;
 
-import lombok.Getter;
-import lombok.Setter;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationManager;
 import org.hswebframework.web.authorization.AuthenticationRequest;
-import org.hswebframework.web.authorization.builder.DataAccessConfigBuilderFactory;
-import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
-import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.core.Ordered;
 import org.springframework.core.annotation.Order;
-import org.springframework.util.StringUtils;
 import reactor.core.publisher.Mono;
 
-import javax.annotation.PostConstruct;
-import javax.validation.ValidationException;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Optional;
 
 /**
  * @author zhouhao
  * @since 3.0.0-RC
  */
-@ConfigurationProperties(prefix = "hsweb")
+
 @Order(Ordered.HIGHEST_PRECEDENCE)
 public class EmbedAuthenticationManager implements AuthenticationManager {
 
-    private Map<String, Authentication> authentications = new HashMap<>();
-
-    @Autowired(required = false)
-    private DataAccessConfigBuilderFactory dataAccessConfigBuilderFactory = new SimpleDataAccessConfigBuilderFactory();
-
-    @Getter
-    @Setter
-    private Map<String, EmbedAuthenticationProperties> users = new HashMap<>();
-
-    @PostConstruct
-    public void init() {
-        users.forEach((id, properties) -> {
-            if (StringUtils.isEmpty(properties.getId())) {
-                properties.setId(id);
-            }
-            for (EmbedAuthenticationProperties.PermissionInfo permissionInfo : properties.getPermissions()) {
-                for (Map<String, Object> objectMap : permissionInfo.getDataAccesses()) {
-                    for (Map.Entry<String, Object> stringObjectEntry : objectMap.entrySet()) {
-                        if (stringObjectEntry.getValue() instanceof Map) {
-                            Map<?, ?> mapVal = ((Map) stringObjectEntry.getValue());
-                            boolean maybeIsList = mapVal.keySet().stream().allMatch(org.hswebframework.utils.StringUtils::isInt);
-                            if (maybeIsList) {
-                                stringObjectEntry.setValue(mapVal.values());
-                            }
-                        }
-                    }
-                }
-            }
-            authentications.put(id, properties.toAuthentication(dataAccessConfigBuilderFactory));
-        });
-    }
+    @Autowired
+    private EmbedAuthenticationProperties properties;
 
     @Override
-    public Mono<Authentication> authenticate(Mono<AuthenticationRequest> request) {
-        return request.filter(r -> r instanceof PlainTextUsernamePasswordAuthenticationRequest)
-                .map(PlainTextUsernamePasswordAuthenticationRequest.class::cast)
-                .map(pwdReq -> users.values()
-                        .stream()
-                        .filter(user ->
-                                pwdReq.getUsername().equals(user.getUsername())
-                                        && pwdReq.getPassword().equals(user.getPassword()))
-                        .findFirst()
-                        .map(EmbedAuthenticationProperties::getId)
-                        .map(authentications::get)
-                        .orElseThrow(() -> new ValidationException("用户不存在")));
+    public Authentication authenticate(AuthenticationRequest request) {
+        return properties.authenticate(request);
 
     }
 
     @Override
-    public Mono<Authentication> getByUserId(String userId) {
-        return Mono.just(authentications.get(userId));
+    public Optional<Authentication> getByUserId(String userId) {
+        return properties.getAuthentication(userId);
     }
 
-    void addAuthentication(Authentication authentication) {
-        authentications.put(authentication.getUser().getId(), authentication);
-    }
+
 }

+ 62 - 69
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationProperties.java

@@ -1,23 +1,27 @@
 package org.hswebframework.web.authorization.basic.embed;
 
-import com.alibaba.fastjson.JSON;
 import lombok.Getter;
 import lombok.Setter;
 import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.Permission;
-import org.hswebframework.web.authorization.Role;
+import org.hswebframework.web.authorization.AuthenticationRequest;
 import org.hswebframework.web.authorization.builder.DataAccessConfigBuilderFactory;
-import org.hswebframework.web.authorization.simple.SimpleAuthentication;
-import org.hswebframework.web.authorization.simple.SimplePermission;
-import org.hswebframework.web.authorization.simple.SimpleRole;
-import org.hswebframework.web.authorization.simple.SimpleUser;
-
-import java.util.*;
-import java.util.stream.Collectors;
+import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
+import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.util.StringUtils;
+import reactor.core.publisher.Mono;
+
+import javax.validation.ValidationException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 
 /**
  * <pre>
  * hsweb:
+ *    auth:
  *      users:
  *          admin:
  *            name: 超级管理员
@@ -42,72 +46,61 @@ import java.util.stream.Collectors;
  */
 @Getter
 @Setter
-public class EmbedAuthenticationProperties {
-
-    private String id;
-
-    private String name;
-
-    private String username;
-
-    private String type;
-
-    private String password;
-
-    private List<SimpleRole> roles = new ArrayList<>();
-
-    private List<PermissionInfo> permissions = new ArrayList<>();
+@ConfigurationProperties(prefix = "hsweb.auth")
+public class EmbedAuthenticationProperties implements InitializingBean {
 
-    private Map<String, List<String>> permissionsSimple = new HashMap<>();
+    private Map<String, Authentication> authentications = new HashMap<>();
 
     @Getter
     @Setter
-    public static class PermissionInfo {
-        private String id;
-
-        private String name;
-
-        private Set<String> actions = new HashSet<>();
-
-        private List<Map<String, Object>> dataAccesses = new ArrayList<>();
+    private Map<String, EmbedAuthenticationInfo> users = new HashMap<>();
+
+    @Autowired(required = false)
+    private DataAccessConfigBuilderFactory dataAccessConfigBuilderFactory = new SimpleDataAccessConfigBuilderFactory();
+
+    @Override
+    public void afterPropertiesSet() {
+        users.forEach((id, properties) -> {
+            if (StringUtils.isEmpty(properties.getId())) {
+                properties.setId(id);
+            }
+            for (EmbedAuthenticationInfo.PermissionInfo permissionInfo : properties.getPermissions()) {
+                for (Map<String, Object> objectMap : permissionInfo.getDataAccesses()) {
+                    for (Map.Entry<String, Object> stringObjectEntry : objectMap.entrySet()) {
+                        if (stringObjectEntry.getValue() instanceof Map) {
+                            Map<?, ?> mapVal = ((Map) stringObjectEntry.getValue());
+                            boolean maybeIsList = mapVal.keySet().stream().allMatch(org.hswebframework.utils.StringUtils::isInt);
+                            if (maybeIsList) {
+                                stringObjectEntry.setValue(mapVal.values());
+                            }
+                        }
+                    }
+                }
+            }
+            authentications.put(id, properties.toAuthentication(dataAccessConfigBuilderFactory));
+        });
     }
 
-    public Authentication toAuthentication(DataAccessConfigBuilderFactory factory) {
-        SimpleAuthentication authentication = new SimpleAuthentication();
-        SimpleUser user = new SimpleUser();
-        user.setId(id);
-        user.setName(name);
-        user.setUsername(username);
-        user.setType(type);
-        authentication.setUser(user);
-        authentication.setRoles((List) roles);
-        List<Permission> permissionList = new ArrayList<>();
-
-        permissionList.addAll(permissions.stream()
-                .map(info -> {
-                    SimplePermission permission = new SimplePermission();
-                    permission.setId(info.getId());
-                    permission.setName(info.getName());
-                    permission.setActions(info.getActions());
-                    permission.setDataAccesses(info.getDataAccesses()
-                            .stream().map(conf -> factory.create()
-                                    .fromJson(JSON.toJSONString(conf))
-                                    .build()).collect(Collectors.toSet()));
-                    return permission;
-
-                })
-                .collect(Collectors.toList()));
-
-        permissionList.addAll(permissionsSimple.entrySet().stream()
-                .map(entry -> {
-                    SimplePermission permission = new SimplePermission();
-                    permission.setId(entry.getKey());
-                    permission.setActions(new HashSet<>(entry.getValue()));
-                    return permission;
-                }).collect(Collectors.toList()));
+    public Authentication authenticate(AuthenticationRequest request) {
+        if(request instanceof PlainTextUsernamePasswordAuthenticationRequest){
+            PlainTextUsernamePasswordAuthenticationRequest pwdReq = ((PlainTextUsernamePasswordAuthenticationRequest) request);
+            return users.values()
+                    .stream()
+                    .filter(user ->
+                            pwdReq.getUsername().equals(user.getUsername())
+                                    && pwdReq.getPassword().equals(user.getPassword()))
+                    .findFirst()
+                    .map(EmbedAuthenticationInfo::getId)
+                    .map(authentications::get)
+                    .orElseThrow(() -> new ValidationException("用户不存在"));
+        }
+
+        throw new UnsupportedOperationException("不支持的授权请求:"+request);
+    }
 
-        authentication.setPermissions(permissionList);
-        return authentication;
+    public Optional<Authentication> getAuthentication(String userId) {
+        return Optional.ofNullable(authentications.get(userId));
     }
 
+
 }

+ 35 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedReactiveAuthenticationManager.java

@@ -0,0 +1,35 @@
+package org.hswebframework.web.authorization.basic.embed;
+
+import lombok.AllArgsConstructor;
+import org.hswebframework.web.authorization.Authentication;
+import org.hswebframework.web.authorization.AuthenticationRequest;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import reactor.core.publisher.Mono;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+
+@Order(Ordered.HIGHEST_PRECEDENCE)
+@AllArgsConstructor
+public class EmbedReactiveAuthenticationManager implements ReactiveAuthenticationManager {
+
+    private EmbedAuthenticationProperties properties;
+
+    @Override
+    public Mono<Authentication> authenticate(Mono<AuthenticationRequest> request) {
+        return request.map(properties::authenticate);
+
+    }
+
+    @Override
+    public Mono<Authentication> getByUserId(String userId) {
+        return Mono.justOrEmpty(properties.getAuthentication(userId));
+    }
+
+
+}

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

@@ -31,7 +31,6 @@ public final class DefaultDataAccessController implements DataAccessController {
         }
         this.parent = parent;
         addHandler(new CustomDataAccessHandler()).
-                addHandler(new ScriptDataAccessHandler()).
                 addHandler(new FieldFilterDataAccessHandler()).
                 addHandler(new FieldScopeDataAccessHandler());
     }

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

@@ -1,41 +0,0 @@
-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.exception.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.authorization.define.AuthorizingContext;
-
-/**
- * @author zhouhao
- */
-public class ScriptDataAccessHandler implements DataAccessHandler {
-    @Override
-    public boolean isSupport(DataAccessConfig access) {
-        return access instanceof ScriptDataAccessConfig;
-    }
-
-    @Override
-    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}");
-        }
-        String scriptId = DigestUtils.md5Hex(dataAccess.getScript());
-        try {
-            if (!engine.compiled(scriptId)) {
-                engine.compile(scriptId, dataAccess.getScript());
-            }
-            Object success = engine.execute(scriptId, context.getParamContext().getParams()).getIfSuccess();
-            return StringUtils.isTrue(success);
-        } catch (Exception e) {
-            throw new BusinessException("{script_error}", e);
-        }
-    }
-
-}

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

@@ -23,6 +23,7 @@ import io.swagger.annotations.ApiParam;
 import lombok.SneakyThrows;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.events.*;
 import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
@@ -48,7 +49,7 @@ import java.util.function.Function;
 public class AuthorizationController {
 
     @Autowired
-    private AuthenticationManager authenticationManager;
+    private ReactiveAuthenticationManager authenticationManager;
 
     @Autowired
     private ApplicationEventPublisher eventPublisher;

+ 4 - 3
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/web/UserTokenController.java

@@ -5,6 +5,7 @@ import io.swagger.annotations.ApiOperation;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationManager;
 import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.exception.UnAuthorizedException;
 import org.hswebframework.web.authorization.token.TokenState;
@@ -22,10 +23,10 @@ import reactor.core.publisher.Mono;
 @RequestMapping
 @Authorize(permission = "user-token", description = "用户令牌信息管理")
 @Api(tags = "权限-用户令牌管理", value = "权限-用户令牌管理")
-public class UserTokenController {
+public class ReactiveUserTokenController {
     private UserTokenManager userTokenManager;
 
-    private AuthenticationManager authenticationManager;
+    private ReactiveAuthenticationManager authenticationManager;
 
     @Autowired
     @Lazy
@@ -35,7 +36,7 @@ public class UserTokenController {
 
     @Autowired
     @Lazy
-    public void setAuthenticationManager(AuthenticationManager authenticationManager) {
+    public void setAuthenticationManager(ReactiveAuthenticationManager authenticationManager) {
         this.authenticationManager = authenticationManager;
     }
 

+ 2 - 30
hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/TestApplication.java

@@ -1,43 +1,15 @@
 package org.hswebframework.web.authorization.basic.aop;
 
-import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.basic.configuration.EnableAopAuthorize;
-import org.hswebframework.web.authorization.basic.web.GeneratedToken;
-import org.hswebframework.web.authorization.basic.web.ReactiveUserTokenGenerator;
-import org.hswebframework.web.authorization.basic.web.ReactiveUserTokenParser;
-import org.hswebframework.web.authorization.token.ParsedToken;
-import org.hswebframework.web.id.IDGenerator;
 import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
-import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
-import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext;
-import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.reactive.config.EnableWebFlux;
-import org.springframework.web.server.ServerWebExchange;
-import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import reactor.core.publisher.Mono;
 
-import java.util.Collections;
-import java.util.Map;
-
-@SpringBootApplication(exclude = {
-        WebMvcAutoConfiguration.class,
-        ServletWebServerFactoryAutoConfiguration.class,
-        DispatcherServletAutoConfiguration.class})
+@SpringBootApplication
 @EnableAopAuthorize
 public class TestApplication {
 
     public static void main(String[] args) {
-        SpringApplication application=new SpringApplication(TestApplication.class);
-        application.setApplicationContextClass(ReactiveWebServerApplicationContext.class);
-        application.run(args);
+        SpringApplication.run(TestApplication.class,args);
     }
 
 }

+ 0 - 65
hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/aop/WebFluxTests.java

@@ -1,65 +0,0 @@
-package org.hswebframework.web.authorization.basic.aop;
-
-import org.hswebframework.web.authorization.Authentication;
-import org.hswebframework.web.authorization.AuthenticationManager;
-import org.hswebframework.web.authorization.User;
-import org.hswebframework.web.authorization.basic.web.GeneratedToken;
-import org.hswebframework.web.authorization.basic.web.ReactiveUserTokenGenerator;
-import org.hswebframework.web.authorization.basic.web.ReactiveUserTokenParser;
-import org.hswebframework.web.authorization.simple.DefaultAuthorizationAutoConfiguration;
-import org.hswebframework.web.authorization.token.ParsedToken;
-import org.hswebframework.web.authorization.token.UserTokenManager;
-import org.hswebframework.web.id.IDGenerator;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.test.web.reactive.server.WebTestClient;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.reactive.function.client.WebClient;
-import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Flux;
-import reactor.core.publisher.Mono;
-
-import java.util.Collections;
-import java.util.Map;
-
-@WebFluxTest(FluxTestController.class)
-@RunWith(SpringRunner.class)
-@Import(DefaultAuthorizationAutoConfiguration.class)
-public class WebFluxTests {
-
-    @Autowired
-    private WebTestClient client;
-
-    @Autowired
-    private UserTokenManager tokenManager;
-
-
-
-    @Test
-    public void test(){
-
-        tokenManager.signIn("test","test-token","admin",10000).block();
-
-        client.get().uri("/test")
-                .header("token","test")
-                .exchange()
-                .expectStatus()
-                .isOk();
-
-    }
-
-
-
-
-
-}

+ 2 - 1
hsweb-authorization/hsweb-authorization-basic/src/test/resources/application.yml

@@ -1,5 +1,6 @@
 hsweb:
-  users:
+  auth:
+   users:
     admin:
       username: admin
       password: admin

+ 1 - 0
hsweb-commons/hsweb-commons-api/pom.xml

@@ -29,6 +29,7 @@
             <groupId>org.hibernate.javax.persistence</groupId>
             <artifactId>hibernate-jpa-2.1-api</artifactId>
         </dependency>
+
     </dependencies>
 
 </project>

+ 17 - 7
hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/configuration/EasyormRepositoryRegistrar.java

@@ -9,6 +9,8 @@ import org.hswebframework.web.crud.annotation.EnableEasyormRepository;
 import org.hswebframework.web.api.crud.entity.ImplementFor;
 import org.hswebframework.web.crud.annotation.Reactive;
 import org.hswebframework.web.api.crud.entity.GenericEntity;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -138,13 +140,21 @@ public class EasyormRepositoryRegistrar implements ImportBeanDefinitionRegistrar
             registry.registerBeanDefinition(realType.getSimpleName().concat("SyncRepository"), definition);
         }
 
-        RootBeanDefinition definition = new RootBeanDefinition();
-        definition.setTargetType(AutoDDLProcessor.class);
-        definition.setBeanClass(AutoDDLProcessor.class);
-        definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
-        definition.getPropertyValues().add("entities", entityInfos);
-        definition.getPropertyValues().add("reactive", reactive);
-        registry.registerBeanDefinition(AutoDDLProcessor.class.getName(), definition);
+
+        try {
+            BeanDefinition definition = registry.getBeanDefinition(AutoDDLProcessor.class.getName());
+            Set<EntityInfo> infos = (Set) definition.getPropertyValues().get("entities");
+            infos.addAll(entityInfos);
+        } catch (NoSuchBeanDefinitionException e) {
+            RootBeanDefinition definition = new RootBeanDefinition();
+            definition.setTargetType(AutoDDLProcessor.class);
+            definition.setBeanClass(AutoDDLProcessor.class);
+            definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
+            definition.getPropertyValues().add("entities", entityInfos);
+            definition.getPropertyValues().add("reactive", reactive);
+            registry.registerBeanDefinition(AutoDDLProcessor.class.getName(), definition);
+        }
+
 
     }
 

+ 49 - 0
hsweb-core/src/main/java/org/hswebframework/web/event/GenericsPayloadApplicationEvent.java

@@ -0,0 +1,49 @@
+package org.hswebframework.web.event;
+
+import org.springframework.context.PayloadApplicationEvent;
+import org.springframework.core.ResolvableType;
+
+/**
+ * 动态泛型事件,用于动态发布支持泛型的事件
+ * <pre>
+ *     //相当于发布事件: EntityModifyEvent&lt;UserEntity&gt;
+ *     eventPublisher
+ *          .publishEvent(new GenericsPayloadApplicationEvent&lt;&gt;(this, new EntityModifyEvent<>(oldEntity, newEntity), UserEntity.class));
+ *
+ *      //只监听相同泛型事件
+ *      &#064;EventListener
+ *      public handleEvent(EntityModifyEvent&lt;UserEntity&gt; event){
+ *
+ *      }
+ * </pre>
+ *
+ * @author zhouhao
+ * @since 3.0.7
+ */
+public class GenericsPayloadApplicationEvent<E> extends PayloadApplicationEvent<E> {
+
+    private static final long serialVersionUID = 3745888943307798710L;
+
+    //泛型列表
+    private transient Class[] generics;
+
+    //事件类型
+    private transient Class eventType;
+
+    /**
+     * @param source   事件源
+     * @param payload  事件,不能使用匿名内部类
+     * @param generics 泛型列表
+     */
+    public GenericsPayloadApplicationEvent(Object source, E payload, Class... generics) {
+        super(source, payload);
+        this.generics = generics;
+        this.eventType = payload.getClass();
+    }
+
+    @Override
+    public ResolvableType getResolvableType() {
+        return ResolvableType.forClassWithGenerics(PayloadApplicationEvent.class
+                , ResolvableType.forClassWithGenerics(eventType, generics));
+    }
+}

+ 4 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/ActionEntity.java

@@ -1,13 +1,15 @@
 package org.hswebframework.web.system.authorization.api.entity;
 
-import lombok.Getter;
-import lombok.Setter;
+import lombok.*;
 import org.hswebframework.web.api.crud.entity.Entity;
 
 import java.util.Map;
 
 @Getter
 @Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class ActionEntity implements Entity {
 
     private String action;

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

@@ -7,10 +7,7 @@ import org.hswebframework.ezorm.rdb.mapping.annotation.Comment;
 import org.hswebframework.ezorm.rdb.mapping.annotation.JsonCodec;
 import org.hswebframework.web.api.crud.entity.Entity;
 
-import javax.persistence.Column;
-import javax.persistence.Id;
-import javax.persistence.Index;
-import javax.persistence.Table;
+import javax.persistence.*;
 import java.sql.JDBCType;
 import java.util.List;
 import java.util.Set;
@@ -23,6 +20,7 @@ import java.util.Set;
 public class AuthorizationSettingEntity implements Entity {
     @Id
     @Column(length = 32)
+    @GeneratedValue(generator = "md5")
     private String id;
 
     @Column(length = 32, nullable = false, updatable = false)
@@ -55,10 +53,15 @@ public class AuthorizationSettingEntity implements Entity {
     @Comment("可操作权限")
     private Set<String> actions;
 
-    @Column
+    @Column(name = "data_accesses")
     @ColumnType(jdbcType = JDBCType.CLOB)
     @JsonCodec
     @Comment("数据权限")
     private List<DataAccessEntity> dataAccesses;
 
+    @Column
+    private Integer priority;
+
+    @Column
+    private Boolean merge;
 }

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

@@ -10,7 +10,7 @@ import java.util.Set;
 @Setter
 public class DataAccessEntity {
 
-    private Set<String> actions;
+    private String action;
 
     private String type;
 

+ 6 - 3
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-api/src/main/java/org/hswebframework/web/system/authorization/api/entity/PermissionEntity.java

@@ -1,7 +1,6 @@
 package org.hswebframework.web.system.authorization.api.entity;
 
-import lombok.Getter;
-import lombok.Setter;
+import lombok.*;
 import org.hswebframework.ezorm.rdb.mapping.annotation.ColumnType;
 import org.hswebframework.ezorm.rdb.mapping.annotation.Comment;
 import org.hswebframework.ezorm.rdb.mapping.annotation.JsonCodec;
@@ -9,6 +8,7 @@ import org.hswebframework.web.api.crud.entity.GenericEntity;
 
 import javax.persistence.Column;
 import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
 import java.sql.JDBCType;
 import java.util.List;
 import java.util.Map;
@@ -16,6 +16,9 @@ import java.util.Map;
 @Table(name = "s_permission")
 @Getter
 @Setter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
 public class PermissionEntity  extends GenericEntity<String> {
 
     @Column
@@ -26,7 +29,7 @@ public class PermissionEntity  extends GenericEntity<String> {
     @Comment("说明")
     private String describe;
 
-    @Column
+    @Column(nullable = false)
     @Comment("状态")
     private Byte status;
 

+ 18 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/pom.xml

@@ -67,6 +67,24 @@
             <artifactId>r2dbc-h2</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-authorization-api</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-webflux</artifactId>
+            <scope>test</scope>
+        </dependency>
 
     </dependencies>
 

+ 50 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationServiceAutoConfiguration.java

@@ -0,0 +1,50 @@
+package org.hswebframework.web.system.authorization.defaults.configuration;
+
+import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.web.authorization.ReactiveAuthenticationInitializeService;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
+import org.hswebframework.web.system.authorization.api.UserPermissionDimensionProvider;
+import org.hswebframework.web.system.authorization.api.service.reactive.ReactiveUserService;
+import org.hswebframework.web.system.authorization.defaults.service.DefaultReactiveAuthenticationInitializeService;
+import org.hswebframework.web.system.authorization.defaults.service.DefaultReactiveAuthenticationManager;
+import org.hswebframework.web.system.authorization.defaults.service.DefaultReactiveUserService;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class AuthorizationServiceAutoConfiguration {
+
+
+    // TODO: 2019-10-12 condition reactive enabled
+    @Configuration
+    static class ReactiveAuthorizationServiceAutoConfiguration{
+        @ConditionalOnBean(ReactiveRepository.class)
+        @Bean
+        public ReactiveUserService reactiveUserService() {
+            return new DefaultReactiveUserService();
+        }
+
+        @ConditionalOnMissingBean
+        @ConditionalOnBean(ReactiveUserService.class)
+        @Bean
+        public ReactiveAuthenticationManager reactiveAuthenticationManager() {
+            return new DefaultReactiveAuthenticationManager();
+        }
+
+        @Bean
+        @ConditionalOnBean(ReactiveUserService.class)
+        public ReactiveAuthenticationInitializeService reactiveAuthenticationInitializeService() {
+            return new DefaultReactiveAuthenticationInitializeService();
+        }
+
+        @Bean
+        public UserPermissionDimensionProvider userPermissionDimensionProvider(){
+            return new UserPermissionDimensionProvider();
+        }
+    }
+
+
+}

+ 28 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/configuration/AuthorizationWebAutoConfiguration.java

@@ -0,0 +1,28 @@
+package org.hswebframework.web.system.authorization.defaults.configuration;
+
+import org.hswebframework.web.system.authorization.defaults.webflux.WebFluxPermissionController;
+import org.hswebframework.web.system.authorization.defaults.webflux.WebFluxUserController;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AuthorizationWebAutoConfiguration {
+
+
+    @Configuration
+    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
+    public static class WebFluxAuthorizationConfiguration {
+
+        @Bean
+        public WebFluxPermissionController webFluxPermissionController() {
+            return new WebFluxPermissionController();
+        }
+
+        @Bean
+        public WebFluxUserController webFluxUserController() {
+            return new WebFluxUserController();
+        }
+    }
+
+}

+ 137 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/DefaultReactiveAuthenticationInitializeService.java

@@ -0,0 +1,137 @@
+package org.hswebframework.web.system.authorization.defaults.service;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.web.authorization.Authentication;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.ReactiveAuthenticationInitializeService;
+import org.hswebframework.web.authorization.access.DataAccessConfig;
+import org.hswebframework.web.authorization.builder.DataAccessConfigBuilderFactory;
+import org.hswebframework.web.authorization.simple.SimpleAuthentication;
+import org.hswebframework.web.authorization.simple.SimplePermission;
+import org.hswebframework.web.authorization.simple.SimpleUser;
+import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
+import org.hswebframework.web.system.authorization.api.PermissionDimension;
+import org.hswebframework.web.system.authorization.api.PermissionDimensionProvider;
+import org.hswebframework.web.system.authorization.api.entity.AuthorizationSettingEntity;
+import org.hswebframework.web.system.authorization.api.entity.PermissionEntity;
+import org.hswebframework.web.system.authorization.api.entity.UserEntity;
+import org.hswebframework.web.system.authorization.api.service.reactive.ReactiveUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class DefaultReactiveAuthenticationInitializeService
+        implements ReactiveAuthenticationInitializeService {
+
+    @Autowired
+    private ReactiveUserService userService;
+
+    @Autowired
+    private ReactiveRepository<AuthorizationSettingEntity, String> settingRepository;
+
+    @Autowired
+    private ReactiveRepository<PermissionEntity, String> permissionRepository;
+
+    @Autowired(required = false)
+    private DataAccessConfigBuilderFactory builderFactory = new SimpleDataAccessConfigBuilderFactory();
+
+    @Autowired(required = false)
+    private List<PermissionDimensionProvider> dimensionProviders = new ArrayList<>();
+
+    @Override
+    public Mono<Authentication> initUserAuthorization(String userId) {
+        return doInit(userService.findById(userId));
+    }
+
+    public Mono<Authentication> doInit(Mono<UserEntity> userEntityMono) {
+
+        return userEntityMono.flatMap(user -> {
+            SimpleAuthentication authentication = new SimpleAuthentication();
+            authentication.setUser(SimpleUser
+                    .builder()
+                    .id(user.getId())
+                    .name(user.getName())
+                    .username(user.getUsername())
+                    .type(user.getType())
+                    .build());
+            return initPermission(authentication);
+        });
+
+    }
+
+    protected Mono<Authentication> initPermission(SimpleAuthentication authentication) {
+        return Flux.fromIterable(dimensionProviders)
+                .flatMap(provider -> provider.getDimensionByUserId(authentication.getUser().getId()))
+                .collectList()
+                .flatMap(allDimension -> Mono.zip(getAllPermission(),
+                        settingRepository
+                                .createQuery()
+                                .where(AuthorizationSettingEntity::getState, 1)
+                                .in(AuthorizationSettingEntity::getDimension, allDimension
+                                        .stream()
+                                        .map(PermissionDimension::getId)
+                                        .collect(Collectors.toList()))
+                                .fetch()
+                                .collect(Collectors.groupingBy(AuthorizationSettingEntity::getPermission))
+                        , (_p, _s) -> handlePermission(authentication, allDimension, _p, _s)));
+
+    }
+
+    protected SimpleAuthentication handlePermission(SimpleAuthentication authentication,
+                                                    List<PermissionDimension> dimensionList,
+                                                    Map<String, PermissionEntity> permissions,
+                                                    Map<String, List<AuthorizationSettingEntity>> settings) {
+        List<Permission> permissionList = new ArrayList<>();
+        for (PermissionEntity value : permissions.values()) {
+            List<AuthorizationSettingEntity> permissionSettings = settings.get(value.getId());
+            if (CollectionUtils.isEmpty(permissionSettings)) {
+                continue;
+            }
+            permissionSettings.sort(Comparator.comparingInt(e -> e.getPriority() == null ? 0 : e.getPriority()));
+            SimplePermission permission = new SimplePermission();
+            permission.setId(value.getId());
+            permission.setName(value.getName());
+            Map<String, DataAccessConfig> configs = new HashMap<>();
+
+            for (AuthorizationSettingEntity permissionSetting : permissionSettings) {
+
+                boolean merge = Boolean.TRUE.equals(permissionSetting.getMerge());
+
+                if (!merge) {
+                    permission.getActions().clear();
+                }
+
+                if (permissionSetting.getDataAccesses() != null) {
+                    permissionSetting.getDataAccesses()
+                            .stream()
+                            .map(conf -> builderFactory.create().fromMap(conf.getConfig()).build())
+                            .forEach(access -> configs.put(access.getType(), access));
+                }
+
+                permission.getActions().addAll(permissionSetting.getActions());
+
+            }
+            permission.setDataAccesses(new HashSet<>(configs.values()));
+            permissionList.add(permission);
+
+        }
+        authentication.setPermissions(permissionList);
+
+        return authentication;
+    }
+
+    protected Mono<Map<String, PermissionEntity>> getAllPermission() {
+
+        return permissionRepository
+                .createQuery()
+                .where(PermissionEntity::getStatus, 1)
+                .fetch()
+                .collect(Collectors.toMap(PermissionEntity::getId, Function.identity()));
+    }
+
+}

+ 54 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/service/DefaultReactiveAuthenticationManager.java

@@ -0,0 +1,54 @@
+package org.hswebframework.web.system.authorization.defaults.service;
+
+import org.hswebframework.web.authorization.Authentication;
+import org.hswebframework.web.authorization.AuthenticationRequest;
+import org.hswebframework.web.authorization.ReactiveAuthenticationInitializeService;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
+import org.hswebframework.web.authorization.exception.AccessDenyException;
+import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
+import org.hswebframework.web.system.authorization.api.entity.UserEntity;
+import org.hswebframework.web.system.authorization.api.service.reactive.ReactiveUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.CacheManager;
+import org.springframework.cache.support.SimpleValueWrapper;
+import reactor.core.publisher.Mono;
+
+public class DefaultReactiveAuthenticationManager implements ReactiveAuthenticationManager {
+
+    @Autowired
+    private ReactiveUserService reactiveUserService;
+
+    @Autowired
+    private ReactiveAuthenticationInitializeService initializeService;
+
+    @Autowired(required = false)
+    private CacheManager cacheManager;
+
+    @Override
+    public Mono<Authentication> authenticate(Mono<AuthenticationRequest> request) {
+        return request
+                .filter(PlainTextUsernamePasswordAuthenticationRequest.class::isInstance)
+                .switchIfEmpty(Mono.error(() -> new UnsupportedOperationException("不支持的请求类型")))
+                .map(PlainTextUsernamePasswordAuthenticationRequest.class::cast)
+                .flatMap(pwdRequest -> reactiveUserService.findByUsernameAndPassword(pwdRequest.getUsername(), pwdRequest.getPassword()))
+                .switchIfEmpty(Mono.error(() -> new AccessDenyException("密码错误")))
+                .map(UserEntity::getId)
+                .flatMap(this::getByUserId);
+    }
+
+    @Override
+    public Mono<Authentication> getByUserId(String userId) {
+
+        return Mono.justOrEmpty(userId)
+                .flatMap(_id -> Mono.justOrEmpty(cacheManager)
+                        .map(cm -> cm.getCache("user-auth"))
+                        .flatMap(cache -> Mono.justOrEmpty(cache.get(userId))
+                                .switchIfEmpty(initializeService.initUserAuthorization(_id)
+                                        .doOnNext(autz -> cache.put(userId, autz))
+                                        .map(SimpleValueWrapper::new)))
+                        .flatMap(valueWrapper -> Mono.justOrEmpty(valueWrapper.get())))
+                .cast(Authentication.class)
+                .switchIfEmpty(initializeService.initUserAuthorization(userId))
+                .cache();
+    }
+}

+ 72 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/webflux/WebFluxPermissionController.java

@@ -0,0 +1,72 @@
+package org.hswebframework.web.system.authorization.defaults.webflux;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.ezorm.rdb.mapping.defaults.SaveResult;
+import org.hswebframework.web.api.crud.entity.QueryParamEntity;
+import org.hswebframework.web.authorization.Permission;
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.exception.NotFoundException;
+import org.hswebframework.web.system.authorization.api.entity.PermissionEntity;
+import org.reactivestreams.Publisher;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/permission")
+@Authorize(permission = "permission", description = "权限管理")
+public class WebFluxPermissionController {
+
+    @Autowired
+    private ReactiveRepository<PermissionEntity, String> repository;
+
+    @GetMapping
+    @Authorize(action = Permission.ACTION_QUERY)
+    public Flux<PermissionEntity> findAllPermission(QueryParamEntity paramEntity) {
+        return repository.createQuery()
+                .setParam(paramEntity)
+                .fetch();
+    }
+
+    @GetMapping("/{id}")
+    @Authorize(action = Permission.ACTION_QUERY)
+    public Mono<PermissionEntity> getPermission(@PathVariable String id) {
+        return Mono.just(id)
+                .as(repository::findById)
+                .switchIfEmpty(Mono.error(NotFoundException::new));
+    }
+
+    @GetMapping("/count")
+    @Authorize(action = Permission.ACTION_QUERY)
+    public Mono<Integer> countAllPermission(QueryParamEntity paramEntity) {
+        return repository.createQuery()
+                .setParam(paramEntity)
+                .count()
+                .defaultIfEmpty(0);
+    }
+
+    @PatchMapping
+    @Authorize(action = Permission.ACTION_UPDATE)
+    public Mono<SaveResult> savePermission(@RequestBody Publisher<PermissionEntity> paramEntity) {
+        return repository.save(paramEntity);
+    }
+
+    @PutMapping("/status/{status}")
+    @Authorize(action = Permission.ACTION_UPDATE)
+    public Mono<Integer> changePermissionState(@PathVariable Byte status, @RequestBody List<String> idList) {
+
+        return Mono.just(idList)
+                .filter(CollectionUtils::isNotEmpty)
+                .flatMap(list -> repository.createUpdate()
+                        .set(PermissionEntity::getStatus, status)
+                        .where()
+                        .in(PermissionEntity::getId, list)
+                        .execute())
+                .defaultIfEmpty(0);
+
+    }
+}

+ 14 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/java/org/hswebframework/web/system/authorization/defaults/webflux/WebFluxUserController.java

@@ -0,0 +1,14 @@
+package org.hswebframework.web.system.authorization.defaults.webflux;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/user")
+@Authorize(permission = "user",description = "用户管理")
+public class WebFluxUserController {
+
+
+
+}

+ 4 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,4 @@
+# Auto Configure
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.hswebframework.web.system.authorization.defaults.configuration.AuthorizationServiceAutoConfiguration,\
+org.hswebframework.web.system.authorization.defaults.configuration.AuthorizationWebAutoConfiguration

+ 96 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/test/java/org/hswebframework/web/system/authorization/defaults/service/reactive/DefaultReactiveAuthenticationManagerTest.java

@@ -0,0 +1,96 @@
+package org.hswebframework.web.system.authorization.defaults.service.reactive;
+
+import org.hswebframework.ezorm.rdb.mapping.ReactiveRepository;
+import org.hswebframework.web.authorization.Authentication;
+import org.hswebframework.web.authorization.ReactiveAuthenticationManager;
+import org.hswebframework.web.authorization.User;
+import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
+import org.hswebframework.web.system.authorization.api.entity.ActionEntity;
+import org.hswebframework.web.system.authorization.api.entity.AuthorizationSettingEntity;
+import org.hswebframework.web.system.authorization.api.entity.PermissionEntity;
+import org.hswebframework.web.system.authorization.api.entity.UserEntity;
+import org.hswebframework.web.system.authorization.api.service.reactive.ReactiveUserService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = ReactiveTestApplication.class)
+public class DefaultReactiveAuthenticationManagerTest {
+
+    @Autowired
+    private ReactiveUserService userService;
+
+    @Autowired
+    private ReactiveAuthenticationManager reactiveAuthenticationManager;
+
+    @Autowired
+    private ReactiveRepository<PermissionEntity, String> permissionRepository;
+
+    @Autowired
+    private ReactiveRepository<AuthorizationSettingEntity, String> settingRepository;
+
+    @Test
+    public void test() {
+        UserEntity entity = new UserEntity();
+        entity.setName("admin");
+        entity.setUsername("admin");
+        entity.setPassword("admin");
+
+        userService.saveUser(Mono.just(entity))
+                .as(StepVerifier::create)
+                .expectNext(true)
+                .verifyComplete();
+
+        permissionRepository.newInstance()
+                .map(permission -> {
+                    permission.setId("test");
+                    permission.setName("测试");
+                    permission.setActions(Arrays.asList(ActionEntity.builder().action("add").describe("新增").build()));
+                    permission.setStatus((byte) 1);
+                    return permission;
+                })
+                .as(permissionRepository::insert)
+                .as(StepVerifier::create)
+                .expectNext(1)
+                .verifyComplete();
+
+        settingRepository.newInstance()
+                .map(setting -> {
+                    setting.setPermission("test");
+                    setting.setActions(Collections.singleton("add"));
+                    setting.setDimension(entity.getId());
+                    setting.setDimensionName("测试用户");
+                    setting.setState((byte) 1);
+                    return setting;
+                })
+                .as(settingRepository::insert)
+                .as(StepVerifier::create)
+                .expectNext(1)
+                .verifyComplete();
+
+        Mono<Authentication> authenticationMono = reactiveAuthenticationManager
+                .authenticate(Mono.just(new PlainTextUsernamePasswordAuthenticationRequest("admin", "admin")))
+                .cache();
+
+        authenticationMono.map(Authentication::getUser)
+                .map(User::getName)
+                .as(StepVerifier::create)
+                .expectNext("admin")
+                .verifyComplete();
+
+        authenticationMono.map(autz->autz.hasPermission("test","add"))
+                .as(StepVerifier::create)
+                .expectNext(true)
+                .verifyComplete();
+
+    }
+
+}

+ 3 - 6
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/test/java/org/hswebframework/web/system/authorization/defaults/service/reactive/ReactiveTestApplication.java

@@ -1,6 +1,9 @@
 package org.hswebframework.web.system.authorization.defaults.service.reactive;
 
 import org.hswebframework.web.crud.configuration.JdbcSqlExecutorConfiguration;
+import org.hswebframework.web.system.authorization.api.UserPermissionDimensionProvider;
+import org.hswebframework.web.system.authorization.defaults.service.DefaultReactiveAuthenticationInitializeService;
+import org.hswebframework.web.system.authorization.defaults.service.DefaultReactiveAuthenticationManager;
 import org.hswebframework.web.system.authorization.defaults.service.DefaultReactiveUserService;
 import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -18,10 +21,4 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
 public class ReactiveTestApplication {
 
 
-    @Bean
-    public DefaultReactiveUserService defaultReactiveUserService(){
-
-        return new DefaultReactiveUserService();
-    }
-
 }

+ 59 - 0
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-default/src/test/java/org/hswebframework/web/system/authorization/defaults/service/reactive/WebFluxPermissionControllerTest.java

@@ -0,0 +1,59 @@
+package org.hswebframework.web.system.authorization.defaults.service.reactive;
+
+import org.hswebframework.web.crud.annotation.EnableEasyormRepository;
+import org.hswebframework.web.crud.configuration.EasyOrmConfiguration;
+import org.hswebframework.web.crud.configuration.JdbcSqlExecutorConfiguration;
+import org.hswebframework.web.crud.configuration.R2dbcSqlExecutorConfiguration;
+import org.hswebframework.web.system.authorization.api.entity.PermissionEntity;
+import org.hswebframework.web.system.authorization.defaults.configuration.AuthorizationWebAutoConfiguration;
+import org.hswebframework.web.system.authorization.defaults.webflux.WebFluxPermissionController;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration;
+import org.springframework.boot.autoconfigure.r2dbc.ConnectionFactoryAutoConfiguration;
+import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
+import org.springframework.boot.autoconfigure.transaction.reactive.ReactiveTransactionAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import reactor.core.publisher.Mono;
+
+@RunWith(SpringRunner.class)
+@WebFluxTest(WebFluxPermissionController.class)
+@ImportAutoConfiguration(value = {
+        AuthorizationWebAutoConfiguration.class, EasyOrmConfiguration.class,
+        R2dbcSqlExecutorConfiguration.class, ConnectionFactoryAutoConfiguration.class,
+        R2dbcTransactionManagerAutoConfiguration.class,
+        ReactiveTransactionAutoConfiguration.class
+},exclude = {
+        JdbcSqlExecutorConfiguration.class,
+        TransactionAutoConfiguration.class
+})
+@EnableTransactionManagement
+public class WebFluxPermissionControllerTest {
+
+    @Autowired
+    WebTestClient client;
+
+    @Test
+    public void test(){
+        byte[] data=client.get()
+                .uri("/permission/count")
+                //.contentType(MediaType.APPLICATION_JSON)
+//                .body(Mono.just(PermissionEntity
+//                        .builder()
+//                        .name("test")
+//                        .build()),PermissionEntity.class)
+                .exchange()
+                .expectBody()
+                .returnResult()
+                .getResponseBody();
+        System.out.println(new String(data));
+    }
+
+}

+ 0 - 15
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-starter/pom.xml

@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>hsweb-system-authorization</artifactId>
-        <groupId>org.hswebframework.web</groupId>
-        <version>4.0.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>hsweb-system-authorization-starter</artifactId>
-
-
-</project>

+ 0 - 15
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/pom.xml

@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <parent>
-        <artifactId>hsweb-system-authorization</artifactId>
-        <groupId>org.hswebframework.web</groupId>
-        <version>4.0.0-SNAPSHOT</version>
-    </parent>
-    <modelVersion>4.0.0</modelVersion>
-
-    <artifactId>hsweb-system-authorization-web</artifactId>
-
-
-</project>

+ 0 - 2
hsweb-system/hsweb-system-authorization/pom.xml

@@ -13,8 +13,6 @@
     <description>业务模块-权限管理</description>
     <modules>
         <module>hsweb-system-authorization-api</module>
-        <module>hsweb-system-authorization-starter</module>
-        <module>hsweb-system-authorization-web</module>
         <module>hsweb-system-authorization-default</module>
     </modules>
     <artifactId>hsweb-system-authorization</artifactId>

+ 5 - 1
pom.xml

@@ -268,7 +268,11 @@
     </build>
 
     <dependencies>
-
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-indexer</artifactId>
+            <scope>provided</scope>
+        </dependency>
         <dependency>
             <groupId>org.codehaus.groovy</groupId>
             <artifactId>groovy-all</artifactId>