zhouhao 6 سال پیش
والد
کامیت
1f9f788249
17فایلهای تغییر یافته به همراه460 افزوده شده و 41 حذف شده
  1. 8 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationManager.java
  2. 10 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationRequest.java
  3. 21 0
      hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/simple/PlainTextUsernamePasswordAuthenticationRequest.java
  4. 5 8
      hsweb-authorization/hsweb-authorization-api/src/test/java/org/hswebframework/web/authorization/AuthenticationTests.java
  5. 28 0
      hsweb-authorization/hsweb-authorization-basic/pom.xml
  6. 11 1
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java
  7. 88 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationManager.java
  8. 97 0
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationProperties.java
  9. 12 9
      hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java
  10. 4 19
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/src/main/java/org/hswebframework/web/authorization/controller/AuthorizationController.java
  11. 1 1
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/src/main/java/org/hswebframework/web/authorization/controller/UserTokenController.java
  12. 40 0
      hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationManagerTest.groovy
  13. 19 0
      hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/embed/TestApplication.java
  14. 38 0
      hsweb-authorization/hsweb-authorization-basic/src/test/resources/application.yml
  15. 6 0
      hsweb-examples/hsweb-examples-oauth2/hsweb-examples-oauth2-client/src/main/java/org/hswebframework/web/example/oauth2/MemoryAuthenticationManager.java
  16. 49 2
      hsweb-system/hsweb-system-authorization/hsweb-system-authorization-local/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthenticationManager.java
  17. 23 1
      quick-start/README.md

+ 8 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationManager.java

@@ -30,6 +30,14 @@ import java.util.Map;
 public interface AuthenticationManager {
     String USER_AUTH_CACHE_NAME = "user-auth-";
 
+    /**
+     * 进行授权操作
+     *
+     * @param request 授权请求
+     * @return 授权成功则返回用户权限信息
+     */
+    Authentication authenticate(AuthenticationRequest request);
+
     /**
      * 根据用户ID获取权限信息
      *

+ 10 - 0
hsweb-authorization/hsweb-authorization-api/src/main/java/org/hswebframework/web/authorization/AuthenticationRequest.java

@@ -0,0 +1,10 @@
+package org.hswebframework.web.authorization;
+
+import java.io.Serializable;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+public interface AuthenticationRequest extends Serializable {
+}

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

@@ -0,0 +1,21 @@
+package org.hswebframework.web.authorization.simple;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.hswebframework.web.authorization.AuthenticationRequest;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class PlainTextUsernamePasswordAuthenticationRequest implements AuthenticationRequest {
+    private String username;
+
+    private String password;
+}

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

@@ -1,12 +1,7 @@
 package org.hswebframework.web.authorization;
 
-import com.alibaba.fastjson.JSON;
-import org.hswebframework.web.authorization.access.DataAccessConfig;
-import org.hswebframework.web.authorization.access.FieldFilterDataAccessConfig;
-import org.hswebframework.web.authorization.access.ScopeDataAccessConfig;
 import org.hswebframework.web.authorization.builder.AuthenticationBuilder;
 import org.hswebframework.web.authorization.exception.UnAuthorizedException;
-import org.hswebframework.web.authorization.simple.SimpleFiledScopeDataAccessConfig;
 import org.hswebframework.web.authorization.simple.builder.SimpleAuthenticationBuilder;
 import org.hswebframework.web.authorization.simple.builder.SimpleDataAccessConfigBuilderFactory;
 import org.hswebframework.web.authorization.token.*;
@@ -14,12 +9,9 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.Set;
 
-import static org.hswebframework.web.authorization.Permission.scope;
 import static org.junit.Assert.*;
 
 public class AuthenticationTests {
@@ -102,6 +94,11 @@ public class AuthenticationTests {
 
         //初始化权限管理器,用于获取用户的权限信息
         AuthenticationManager authenticationManager = new AuthenticationManager() {
+            @Override
+            public Authentication authenticate(AuthenticationRequest request) {
+                return null;
+            }
+
             @Override
             public Authentication getByUserId(String userId) {
                 if (userId.equals("admin")) {

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

@@ -44,6 +44,34 @@
             <groupId>org.hswebframework</groupId>
             <artifactId>hsweb-easy-orm-rdb</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-spring-boot-starter</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-tests</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.0.26</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+
         <dependency>
             <groupId>org.hswebframework.web</groupId>
             <artifactId>hsweb-commons-controller</artifactId>

+ 11 - 1
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/configuration/AuthorizingHandlerAutoConfiguration.java

@@ -1,8 +1,10 @@
 package org.hswebframework.web.authorization.basic.configuration;
 
+import org.hswebframework.web.authorization.AuthenticationManager;
 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.handler.DefaultAuthorizingHandler;
 import org.hswebframework.web.authorization.basic.handler.access.DefaultDataAccessController;
 import org.hswebframework.web.authorization.basic.web.*;
@@ -11,6 +13,8 @@ import org.hswebframework.web.authorization.token.UserTokenManager;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -59,12 +63,18 @@ public class AuthorizingHandlerAutoConfiguration {
         return new WebMvcConfigurerAdapter() {
             @Override
             public void addInterceptors(InterceptorRegistry registry) {
-                registry.addInterceptor(new WebUserTokenInterceptor(userTokenManager, userTokenParser,parser));
+                registry.addInterceptor(new WebUserTokenInterceptor(userTokenManager, userTokenParser, parser));
                 super.addInterceptors(registry);
             }
         };
     }
 
+    @Bean
+    @ConditionalOnMissingBean(AuthenticationManager.class)
+    public AuthenticationManager embedAuthenticationManager() {
+        return new EmbedAuthenticationManager();
+    }
+
     @Bean
     public UserOnSignIn userOnSignIn(UserTokenManager userTokenManager) {
         return new UserOnSignIn(userTokenManager);

+ 88 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationManager.java

@@ -0,0 +1,88 @@
+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.validate.ValidationException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+@ConfigurationProperties(prefix = "hsweb")
+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());
+                            }
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    @Override
+    public Authentication authenticate(AuthenticationRequest request) {
+        if (request instanceof PlainTextUsernamePasswordAuthenticationRequest) {
+            return sync(users.values().stream()
+                    .filter(user ->
+                            ((PlainTextUsernamePasswordAuthenticationRequest) request).getUsername().equals(user.getUsername())
+                                    && ((PlainTextUsernamePasswordAuthenticationRequest) request).getPassword().equals(user.getPassword()))
+                    .findFirst()
+                    .map(properties -> properties.toAuthentication(dataAccessConfigBuilderFactory))
+                    .orElseThrow(() -> new ValidationException("用户不存在")));
+        }
+
+        throw new UnsupportedOperationException("不支持的授权类型:" + request);
+
+    }
+
+    @Override
+    public Authentication getByUserId(String userId) {
+        return authentications.get(userId);
+    }
+
+    @Override
+    public Authentication sync(Authentication authentication) {
+        authentications.put(authentication.getUser().getId(), authentication);
+        return authentication;
+    }
+
+    void addAuthentication(Authentication authentication) {
+        sync(authentication);
+    }
+}

+ 97 - 0
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationProperties.java

@@ -0,0 +1,97 @@
+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.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 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<>();
+
+    @Getter
+    @Setter
+    public static class PermissionInfo {
+        private String id;
+
+        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 = permissions.stream()
+                .map(info -> {
+                    SimplePermission permission = new SimplePermission();
+                    permission.setId(info.getId());
+                    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());
+
+        authentication.setPermissions(permissionList);
+        return authentication;
+    }
+
+}

+ 12 - 9
hsweb-authorization/hsweb-authorization-basic/src/main/java/org/hswebframework/web/authorization/basic/handler/DefaultAuthorizingHandler.java

@@ -1,6 +1,7 @@
 package org.hswebframework.web.authorization.basic.handler;
 
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.collections.CollectionUtils;
 import org.hswebframework.expands.script.engine.DynamicScriptEngine;
 import org.hswebframework.expands.script.engine.DynamicScriptEngineFactory;
 import org.hswebframework.web.authorization.Authentication;
@@ -54,7 +55,7 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
 
     @Override
     public void handRBAC(AuthorizingContext context) {
-        if(handleEvent(context,HandleType.RBAC)){
+        if (handleEvent(context, HandleType.RBAC)) {
             return;
         }
         //进行rdac权限控制
@@ -63,8 +64,9 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         handleExpression(context.getAuthentication(), context.getDefinition(), context.getParamContext());
 
     }
-    private boolean handleEvent(AuthorizingContext context,HandleType type){
-        if(null!=eventPublisher) {
+
+    private boolean handleEvent(AuthorizingContext context, HandleType type) {
+        if (null != eventPublisher) {
             AuthorizingHandleBeforeEvent event = new AuthorizingHandleBeforeEvent(context, type);
             eventPublisher.publishEvent(event);
             if (!event.isExecute()) {
@@ -77,16 +79,17 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         }
         return false;
     }
+
     public void handleDataAccess(AuthorizingContext context) {
 
         if (dataAccessController == null) {
             logger.warn("dataAccessController is null,skip result access control!");
             return;
         }
-        if(context.getDefinition().getDataAccessDefinition()==null){
+        if (context.getDefinition().getDataAccessDefinition() == null) {
             return;
         }
-        if(handleEvent(context,HandleType.DATA)){
+        if (handleEvent(context, HandleType.DATA)) {
             return;
         }
 
@@ -160,7 +163,7 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
                 logger.info("do permission access handle : permissions{}({}),actions{} ,definition:{}.{} ({})",
                         definition.getPermissionDescription(),
                         permissionsDef, actionsDef
-                        ,definition.getPermissions(),
+                        , definition.getPermissions(),
                         definition.getActions(),
                         definition.getLogical());
             }
@@ -188,14 +191,14 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
                         return logicalIsOr || permission.getActions().containsAll(actions);
                     }).collect(Collectors.toList());
             access = logicalIsOr ?
-                    permissions.size() > 0 :
+                    CollectionUtils.isNotEmpty(permissions) :
                     //权限数量和配置的数量相同
                     permissions.size() == permissionsDef.size();
         }
         //控制角色
         if (!rolesDef.isEmpty()) {
             if (logger.isInfoEnabled()) {
-                logger.info("do role access handle : roles{} , definition:{}", rolesDef,definition.getRoles());
+                logger.info("do role access handle : roles{} , definition:{}", rolesDef, definition.getRoles());
             }
             Function<Predicate<Role>, Boolean> func = logicalIsOr
                     ? authentication.getRoles().stream()::anyMatch
@@ -205,7 +208,7 @@ public class DefaultAuthorizingHandler implements AuthorizingHandler {
         //控制用户
         if (!usersDef.isEmpty()) {
             if (logger.isInfoEnabled()) {
-                logger.info("do user access handle : users{} , definition:{} ", usersDef,definition.getUser());
+                logger.info("do user access handle : users{} , definition:{} ", usersDef, definition.getUser());
             }
             Function<Predicate<String>, Boolean> func = logicalIsOr
                     ? usersDef.stream()::anyMatch

+ 4 - 19
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/src/main/java/org/hswebframework/web/authorization/controller/AuthorizationController.java

@@ -15,7 +15,7 @@
  *
  */
 
-package org.hswebframework.web.authorization.controller;
+package org.hswebframework.web.authorization.basic.web;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -26,12 +26,9 @@ import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationManager;
 import org.hswebframework.web.authorization.annotation.Authorize;
 import org.hswebframework.web.authorization.listener.event.*;
-import org.hswebframework.web.commons.entity.DataStatus;
+import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
 import org.hswebframework.web.controller.message.ResponseMessage;
-import org.hswebframework.web.entity.authorization.UserEntity;
 import org.hswebframework.web.logging.AccessLogger;
-import org.hswebframework.web.service.authorization.UserService;
-import org.hswebframework.web.validate.ValidationException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.http.MediaType;
@@ -53,9 +50,6 @@ import static org.hswebframework.web.controller.message.ResponseMessage.ok;
 @Api(tags = "权限-用户授权", value = "授权")
 public class AuthorizationController {
 
-    @Autowired
-    private UserService userService;
-
     @Autowired
     private AuthenticationManager authenticationManager;
 
@@ -108,20 +102,11 @@ public class AuthorizationController {
             password = decodeEvent.getPassword();
             AuthorizationBeforeEvent beforeEvent = new AuthorizationBeforeEvent(username, password, parameterGetter);
             eventPublisher.publishEvent(beforeEvent);
-            UserEntity entity = userService.selectByUserNameAndPassword(username, password);
-            if (entity == null) {
-                reason = AuthorizationFailedEvent.Reason.PASSWORD_ERROR;
-                throw new ValidationException("密码错误", "password");
-            }
-            if (!DataStatus.STATUS_ENABLED.equals(entity.getStatus())) {
-                reason = AuthorizationFailedEvent.Reason.USER_DISABLED;
-                throw new ValidationException("用户已被禁用", "username");
-            }
             // 验证通过
-            Authentication authentication = authenticationManager.getByUserId(entity.getId());
+            Authentication authentication = authenticationManager.authenticate(new PlainTextUsernamePasswordAuthenticationRequest(username, password));
             //触发授权成功事件
             AuthorizationSuccessEvent event = new AuthorizationSuccessEvent(authentication, parameterGetter);
-            event.getResult().put("userId", entity.getId());
+            event.getResult().put("userId", authentication.getUser().getId());
             eventPublisher.publishEvent(event);
             return ok(event.getResult());
         } catch (Exception e) {

+ 1 - 1
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-web/src/main/java/org/hswebframework/web/authorization/controller/UserTokenController.java

@@ -1,4 +1,4 @@
-package org.hswebframework.web.authorization.controller;
+package org.hswebframework.web.authorization.basic.web;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;

+ 40 - 0
hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/embed/EmbedAuthenticationManagerTest.groovy

@@ -0,0 +1,40 @@
+package org.hswebframework.web.authorization.basic.embed
+
+import org.hswebframework.web.authorization.Authentication
+import org.hswebframework.web.authorization.AuthenticationManager
+import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.boot.test.context.SpringBootTest
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.web.WebAppConfiguration
+import spock.lang.Specification
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+@WebAppConfiguration
+@ContextConfiguration
+@SpringBootTest(classes = [TestApplication.class], properties = ["classpath:application.yml"])
+class EmbedAuthenticationManagerTest extends Specification {
+
+    @Autowired
+    private AuthenticationManager manager;
+
+
+    def "Test"() {
+        setup:
+        Authentication authentication = manager.authenticate(new PlainTextUsernamePasswordAuthenticationRequest("admin", "admin"));
+        expect:
+        authentication != null
+        authentication.getUser() != null
+        authentication.getUser().getName() == "超级管理员"
+        authentication.hasPermission("user-manager", "query")
+        authentication.getPermission("user-manager") != null
+        authentication.hasRole("user")
+        authentication.getPermission("user-manager")
+                .get().findDenyFields("query") != null
+        authentication.getPermission("user-manager")
+                .get().findDenyFields("query").contains("password")
+    }
+}

+ 19 - 0
hsweb-authorization/hsweb-authorization-basic/src/test/java/org/hswebframework/web/authorization/basic/embed/TestApplication.java

@@ -0,0 +1,19 @@
+package org.hswebframework.web.authorization.basic.embed;
+
+import org.hswebframework.web.authorization.basic.configuration.AopAuthorizeAutoConfiguration;
+import org.hswebframework.web.authorization.basic.configuration.AuthorizingHandlerAutoConfiguration;
+import org.hswebframework.web.authorization.basic.configuration.EnableAopAuthorize;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+/**
+ * @author zhouhao
+ * @since 3.0.0-RC
+ */
+@SpringBootApplication
+@WebAppConfiguration
+@EnableAopAuthorize
+public class TestApplication {
+
+}

+ 38 - 0
hsweb-authorization/hsweb-authorization-basic/src/test/resources/application.yml

@@ -0,0 +1,38 @@
+
+spring:
+    aop:
+        auto: true
+        proxy-target-class: true
+    datasource:
+       url : jdbc:h2:mem:example-oauth2-client
+       username : sa
+       password :
+       type: com.alibaba.druid.pool.DruidDataSource
+       driver-class-name : org.h2.Driver
+    cache:
+       type: simple
+hsweb:
+    app:
+      name: hsweb-oauth2 客户端示例
+      version: 3.0.0
+    users:
+        admin:
+          name: 超级管理员
+          username: admin
+          password: admin
+          roles: #用户的角色
+            - id: admin
+              name: 管理员
+            - id: user
+              name: 用户
+          permissions:
+            - id: user-manager
+              actions: query,get,update,delete
+              dataAccesses:
+                - action: query
+                  type: DENY_FIELDS
+                  fields:
+                    - password
+                    - salt
+server:
+  port: 8808

+ 6 - 0
hsweb-examples/hsweb-examples-oauth2/hsweb-examples-oauth2-client/src/main/java/org/hswebframework/web/example/oauth2/MemoryAuthenticationManager.java

@@ -2,6 +2,7 @@ package org.hswebframework.web.example.oauth2;
 
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.AuthenticationRequest;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -13,6 +14,11 @@ public class MemoryAuthenticationManager implements AuthenticationManager {
         users.put(authentication.getUser().getId(), authentication);
     }
 
+    @Override
+    public Authentication authenticate(AuthenticationRequest request) {
+        return null;
+    }
+
     @Override
     public Authentication getByUserId(String userId) {
 

+ 49 - 2
hsweb-system/hsweb-system-authorization/hsweb-system-authorization-local/src/main/java/org/hswebframework/web/service/authorization/simple/SimpleAuthenticationManager.java

@@ -3,10 +3,21 @@ package org.hswebframework.web.service.authorization.simple;
 import org.hswebframework.web.authorization.Authentication;
 import org.hswebframework.web.authorization.AuthenticationInitializeService;
 import org.hswebframework.web.authorization.AuthenticationManager;
+import org.hswebframework.web.authorization.AuthenticationRequest;
+import org.hswebframework.web.authorization.listener.event.AuthorizationFailedEvent;
+import org.hswebframework.web.authorization.simple.PlainTextUsernamePasswordAuthenticationRequest;
+import org.hswebframework.web.commons.entity.DataStatus;
+import org.hswebframework.web.entity.authorization.UserEntity;
+import org.hswebframework.web.service.authorization.UserService;
+import org.hswebframework.web.validate.ValidationException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
 import org.springframework.cache.annotation.CachePut;
 import org.springframework.cache.annotation.Cacheable;
 
+import java.util.function.Supplier;
+
 /**
  * @author zhouhao
  */
@@ -14,6 +25,12 @@ public class SimpleAuthenticationManager implements AuthenticationManager {
 
     private AuthenticationInitializeService authenticationInitializeService;
 
+    @Autowired
+    private UserService userService;
+
+    @Autowired(required = false)
+    private CacheManager cacheManager;
+
     public SimpleAuthenticationManager() {
     }
 
@@ -27,9 +44,39 @@ public class SimpleAuthenticationManager implements AuthenticationManager {
     }
 
     @Override
-    @Cacheable(value = USER_AUTH_CACHE_NAME, key = "#userId")
+    public Authentication authenticate(AuthenticationRequest request) {
+        if (request instanceof PlainTextUsernamePasswordAuthenticationRequest) {
+            String username = ((PlainTextUsernamePasswordAuthenticationRequest) request).getUsername();
+            String password = ((PlainTextUsernamePasswordAuthenticationRequest) request).getPassword();
+            UserEntity userEntity = userService.selectByUserNameAndPassword(username, password);
+            if (userEntity == null) {
+                throw new ValidationException("密码错误", "password");
+            }
+            if (!DataStatus.STATUS_ENABLED.equals(userEntity.getStatus())) {
+                throw new ValidationException("用户已被禁用", "username");
+            }
+            return getByUserId(userEntity.getId());
+        }
+        return null;
+    }
+
+    @Override
+//    @Cacheable(value = USER_AUTH_CACHE_NAME, key = "#userId")
     public Authentication getByUserId(String userId) {
-        return authenticationInitializeService.initUserAuthorization(userId);
+        Supplier<Authentication> supplier = () -> authenticationInitializeService.initUserAuthorization(userId);
+
+        if (null != cacheManager) {
+            Cache cache = cacheManager.getCache(USER_AUTH_CACHE_NAME);
+            Cache.ValueWrapper wrapper = cache.get(userId);
+            if (wrapper == null) {
+                Authentication authentication = supplier.get();
+                cache.put(userId, authentication);
+                return authentication;
+            } else {
+                return (Authentication) wrapper.get();
+            }
+        }
+        return supplier.get();
     }
 
     @Override

+ 23 - 1
quick-start/README.md

@@ -291,4 +291,26 @@ public class MyProjectApplication {
 
 以权限管理模块(`hsweb-system/hsweb-system-authorization`)为例.
 
-TODO
+在pom.xml中引入模块:
+```xml
+<!--权限控制-->
+<dependency>
+    <groupId>org.hswebframework.web</groupId>
+    <artifactId>hsweb-authorization-basic</artifactId>
+    <version>${hsweb.framework.version}</version>
+</dependency>
+
+<!--权限管理-->
+<dependency>
+    <groupId>org.hswebframework.web</groupId>
+    <artifactId>hsweb-system-authorization-starter</artifactId>
+    <version>${hsweb.framework.version}</version>
+</dependency>
+```
+
+![import-authorization-module](./img/import-authorization-module.gif "import-authorization-module")
+
+
+
+
+