Explorar o código

完成oauth2客户端基本实现

zhouhao %!s(int64=8) %!d(string=hai) anos
pai
achega
44b00da1bf
Modificáronse 49 ficheiros con 3309 adicións e 10 borrados
  1. 5 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/pom.xml
  2. 12 10
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2ClientController.java
  3. 58 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2ServerConfigController.java
  4. 55 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2UserTokenController.java
  5. 45 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-api/pom.xml
  6. 27 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-api/src/main/java/org/hswebframework/web/dao/oauth2/client/OAuth2ServerConfigDao.java
  7. 27 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-api/src/main/java/org/hswebframework/web/dao/oauth2/client/OAuth2UserTokenDao.java
  8. 44 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-mybatis/pom.xml
  9. 71 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/oauth2/client/OAuth2ServerConfigMapper.xml
  10. 71 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/oauth2/client/OAuth2UserTokenMapper.xml
  11. 36 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/pom.xml
  12. 40 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/pom.xml
  13. 155 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/OAuth2ServerConfigEntity.java
  14. 184 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/OAuth2UserTokenEntity.java
  15. 178 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/SimpleOAuth2ServerConfigEntity.java
  16. 199 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/SimpleOAuth2UserTokenEntity.java
  17. 42 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-api/pom.xml
  18. 29 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-api/src/main/java/org/hswebframework/web/service/oauth2.client/OAuth2ServerConfigService.java
  19. 33 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-api/src/main/java/org/hswebframework/web/service/oauth2.client/OAuth2UserTokenService.java
  20. 51 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/pom.xml
  21. 83 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2RequestService.java
  22. 47 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2ServerConfigService.java
  23. 163 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2SessionBuilder.java
  24. 70 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2UserTokenService.java
  25. 34 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/ResponseConvertHandler.java
  26. 28 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/ResponseJudge.java
  27. 150 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/SimpleOAuth2Request.java
  28. 115 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/SimpleOAuth2Response.java
  29. 31 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/UnCheck.java
  30. 69 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/builder/SimpleOAuth2RequestBuilder.java
  31. 130 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/builder/SimpleOAuth2RequestBuilderFactory.java
  32. 30 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseConvertForProviderDefinition.java
  33. 30 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseConvertForServerIdDefinition.java
  34. 29 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseJudgeForProviderDefinition.java
  35. 30 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseJudgeForServerIdDefinition.java
  36. 54 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/AuthorizationCodeSession.java
  37. 40 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/CachedOAuth2Session.java
  38. 178 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/DefaultOAuth2Session.java
  39. 46 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/PasswordSession.java
  40. 34 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/pom.xml
  41. 91 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/pom.xml
  42. 46 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/main/java/org/hswebframework/web/service/oauth2/client/starter/DefaultResponseJudge.java
  43. 52 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/main/java/org/hswebframework/web/service/oauth2/client/starter/OAuth2ClientAutoConfiguration.java
  44. 82 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/main/resources/hsweb-starter.js
  45. 123 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/java/org/hswebframework/web/starter/oauth2/client/OAuth2ServerConfigTests.java
  46. 58 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/java/org/hswebframework/web/starter/oauth2/client/QQResponseConvertSupport.java
  47. 87 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/java/org/hswebframework/web/starter/oauth2/client/QQResponseJudgeSupport.java
  48. 13 0
      hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/resources/application.yml
  49. 4 0
      hsweb-system/hsweb-system-oauth2-client/pom.xml

+ 5 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/pom.xml

@@ -41,6 +41,11 @@
             <artifactId>hsweb-commons-controller</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-service-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.hswebframework.web</groupId>
             <artifactId>hsweb-authorization-oauth2-client</artifactId>

+ 12 - 10
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2ClientController.java

@@ -26,10 +26,10 @@ import org.hswebframework.web.id.IDGenerator;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.view.RedirectView;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
-import java.util.Map;
 
 /**
  * @author zhouhao
@@ -56,17 +56,19 @@ public class OAuth2ClientController {
     }
 
     @GetMapping("/callback/{serverId}")
-    public ModelAndView callback(@RequestParam(defaultValue = "/") String redirect
-            , @PathVariable String serverId
-            , @RequestParam String code
-            , @RequestParam String state
-            , @RequestParam Map<String, Object> param
-            , HttpSession session) {
+    public RedirectView callback(@RequestParam(defaultValue = "/") String redirect,
+                                 @PathVariable String serverId,
+                                 @RequestParam String code,
+                                 @RequestParam String state,
+                                 HttpServletRequest request,
+                                 HttpSession session) {
         try {
             String cachedState = (String) session.getAttribute(STATE_SESSION_KEY);
             if (!state.equals(cachedState)) throw new BusinessException("state error");
-            oAuth2RequestService.doEvent(serverId, new OAuth2CodeAuthBeforeEvent(code, state, param::get));
-            return new ModelAndView("redirect:" + redirect);
+
+            oAuth2RequestService.doEvent(serverId, new OAuth2CodeAuthBeforeEvent(code, state, request::getParameter));
+            // TODO: 17-4-7 验证并解码redirect
+            return new RedirectView(redirect);
         } finally {
             session.removeAttribute(STATE_SESSION_KEY);
         }

+ 58 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2ServerConfigController.java

@@ -0,0 +1,58 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ *
+ */
+
+package org.hswebframework.web.authorization.oauth2.controller;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.controller.GenericEntityController;
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.oauth2.client.OAuth2ServerConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * OAuth2服务配置
+ *
+ * @author hsweb-generator-online
+ */
+@RestController
+@RequestMapping("${hsweb.web.mappings.oauth2-server-config:oauth2-server-config}")
+@Authorize(permission = "oauth2-server-config")
+@AccessLogger("OAuth2服务配置")
+public class OAuth2ServerConfigController implements GenericEntityController<OAuth2ServerConfigEntity, String, QueryParamEntity, OAuth2ServerConfigEntity> {
+
+    private OAuth2ServerConfigService oAuth2ServerConfigService;
+
+    @Override
+    public OAuth2ServerConfigEntity modelToEntity(OAuth2ServerConfigEntity model, OAuth2ServerConfigEntity entity) {
+        return model;
+    }
+
+    @Autowired
+    public void setOAuth2ServerConfigService(OAuth2ServerConfigService oAuth2ServerConfigService) {
+        this.oAuth2ServerConfigService = oAuth2ServerConfigService;
+    }
+
+    @Override
+    public OAuth2ServerConfigService getService() {
+        return oAuth2ServerConfigService;
+    }
+}

+ 55 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-controller/src/main/java/org/hswebframework/web/authorization/oauth2/controller/OAuth2UserTokenController.java

@@ -0,0 +1,55 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ *
+ */
+
+package org.hswebframework.web.authorization.oauth2.controller;
+
+import org.hswebframework.web.authorization.annotation.Authorize;
+import org.hswebframework.web.commons.entity.param.QueryParamEntity;
+import org.hswebframework.web.controller.GenericEntityController;
+import org.hswebframework.web.controller.QueryController;
+import org.hswebframework.web.entity.oauth2.client.OAuth2UserTokenEntity;
+import org.hswebframework.web.logging.AccessLogger;
+import org.hswebframework.web.service.oauth2.client.OAuth2UserTokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * OAuth2用户授权信息
+ *
+ * @author hsweb-generator-online
+ */
+@RestController
+@RequestMapping("${hsweb.web.mappings.oauth2-user-token:oauth2-user-token}")
+@Authorize(permission = "oauth2-user-token")
+@AccessLogger("OAuth2用户授权信息")
+public class OAuth2UserTokenController
+        implements QueryController<OAuth2UserTokenEntity, String, QueryParamEntity> {
+
+    private OAuth2UserTokenService oAuth2UserTokenService;
+
+    @Autowired
+    public void setOAuth2UserTokenService(OAuth2UserTokenService oAuth2UserTokenService) {
+        this.oAuth2UserTokenService = oAuth2UserTokenService;
+    }
+
+    @Override
+    public OAuth2UserTokenService getService() {
+        return oAuth2UserTokenService;
+    }
+}

+ 45 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-api/pom.xml

@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 
+  ~   Copyright 2016 http://www.hswebframework.org
+  ~  
+  ~   Licensed under the Apache License, Version 2.0 (the "License");
+  ~   you may not use this file except in compliance with the License.
+  ~   You may obtain a copy of the License at
+  ~  
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~  
+  ~   Unless required by applicable law or agreed to in writing, software
+  ~   distributed under the License is distributed on an "AS IS" BASIS,
+  ~   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~   See the License for the specific language governing permissions and
+  ~   limitations under the License.
+  ~  
+  -->
+
+<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-oauth2-client-dao</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-dao-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-entity</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-dao-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 27 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-api/src/main/java/org/hswebframework/web/dao/oauth2/client/OAuth2ServerConfigDao.java

@@ -0,0 +1,27 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.dao.oauth2.client;
+
+import org.hswebframework.web.dao.CrudDao;
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+
+/**
+*  OAuth2服务配置 DAO接口
+*  @author hsweb-generator-online
+ */
+public interface OAuth2ServerConfigDao extends CrudDao<OAuth2ServerConfigEntity,String> {
+}

+ 27 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-api/src/main/java/org/hswebframework/web/dao/oauth2/client/OAuth2UserTokenDao.java

@@ -0,0 +1,27 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.dao.oauth2.client;
+
+import org.hswebframework.web.dao.CrudDao;
+import org.hswebframework.web.entity.oauth2.client.OAuth2UserTokenEntity;
+
+/**
+*  OAuth2用户授权信息 DAO接口
+*  @author hsweb-generator-online
+ */
+public interface OAuth2UserTokenDao extends CrudDao<OAuth2UserTokenEntity,String> {
+}

+ 44 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-mybatis/pom.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 
+  ~   Copyright 2016 http://www.hswebframework.org
+  ~  
+  ~   Licensed under the Apache License, Version 2.0 (the "License");
+  ~   you may not use this file except in compliance with the License.
+  ~   You may obtain a copy of the License at
+  ~  
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~  
+  ~   Unless required by applicable law or agreed to in writing, software
+  ~   distributed under the License is distributed on an "AS IS" BASIS,
+  ~   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~   See the License for the specific language governing permissions and
+  ~   limitations under the License.
+  ~  
+  -->
+
+<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-oauth2-client-dao</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-dao-mybatis</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-dao-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-dao-mybatis</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 71 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/oauth2/client/OAuth2ServerConfigMapper.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hswebframework.web.dao.oauth2.client.OAuth2ServerConfigDao">
+    <resultMap id="OAuth2ServerConfigResultMap" type="org.hswebframework.web.entity.oauth2.client.SimpleOAuth2ServerConfigEntity">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="name" column="name" javaType="String" jdbcType="VARCHAR"/>
+        <result property="describe" column="describe" javaType="String" jdbcType="VARCHAR"/>
+        <result property="apiBaseUrl" column="api_base_url" javaType="String" jdbcType="VARCHAR"/>
+        <result property="authUrl" column="auth_url" javaType="String" jdbcType="VARCHAR"/>
+        <result property="accessTokenUrl" column="access_token_url" javaType="String" jdbcType="VARCHAR"/>
+        <result property="redirectUri" column="redirect_uri" javaType="String" jdbcType="VARCHAR"/>
+        <result property="clientId" column="client_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="clientSecret" column="client_secret" javaType="String" jdbcType="VARCHAR"/>
+        <result property="provider" column="provider" javaType="String" jdbcType="VARCHAR"/>
+        <result property="properties" column="properties" javaType="java.util.Map" jdbcType="CLOB"/>
+        <result property="enabled" column="enabled" javaType="Boolean" jdbcType="DECIMAL"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'OAuth2ServerConfigResultMap'"/>
+        <bind name="tableName" value="'s_oauth2_server'"/>
+    </sql>
+
+    <insert id="insert" parameterType="org.hswebframework.web.entity.oauth2.client.SimpleOAuth2ServerConfigEntity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="deleteByPk" parameterType="String">
+        delete from s_oauth2_server where u_id =#{id}
+    </delete>
+
+    <delete id="delete" parameterType="org.hswebframework.web.commons.entity.Entity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hswebframework.web.commons.entity.Entity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="query" parameterType="org.hswebframework.web.commons.entity.Entity" resultMap="OAuth2ServerConfigResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="count" parameterType="org.hswebframework.web.commons.entity.Entity" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 71 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/hsweb-system-oauth2-client-dao-mybatis/src/main/resources/org/hswebframework/web/dao/mybatis/mappers/oauth2/client/OAuth2UserTokenMapper.xml

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.hswebframework.web.dao.oauth2.client.OAuth2UserTokenDao">
+    <resultMap id="OAuth2UserTokenResultMap" type="org.hswebframework.web.entity.oauth2.client.SimpleOAuth2UserTokenEntity">
+        <id property="id" column="u_id" javaType="string" jdbcType="VARCHAR"/>
+        <result property="clientUserId" column="client_user_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="serverUserId" column="server_user_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="serverId" column="server_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="clientId" column="client_id" javaType="String" jdbcType="VARCHAR"/>
+        <result property="accessToken" column="access_token" javaType="String" jdbcType="VARCHAR"/>
+        <result property="refreshToken" column="refresh_token" javaType="String" jdbcType="VARCHAR"/>
+        <result property="expiresIn" column="expires_in" javaType="Integer" jdbcType="DECIMAL"/>
+        <result property="scope" column="scope" javaType="String" jdbcType="CLOB"/>
+        <result property="createTime" column="create_time" javaType="Long" jdbcType="DECIMAL"/>
+        <result property="updateTime" column="update_time" javaType="Long" jdbcType="DECIMAL"/>
+        <result property="grantType" column="grant_type" javaType="String" jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <!--用于动态生成sql所需的配置-->
+    <sql id="config">
+        <bind name="resultMapId" value="'OAuth2UserTokenResultMap'"/>
+        <bind name="tableName" value="'s_oauth2_user_token'"/>
+    </sql>
+
+    <insert id="insert" parameterType="org.hswebframework.web.entity.oauth2.client.SimpleOAuth2UserTokenEntity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildInsertSql"/>
+    </insert>
+
+    <delete id="deleteByPk" parameterType="String">
+        delete from s_oauth2_user_token where u_id =#{id}
+    </delete>
+
+    <delete id="delete" parameterType="org.hswebframework.web.commons.entity.Entity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildDeleteSql"/>
+    </delete>
+
+    <update id="update" parameterType="org.hswebframework.web.commons.entity.Entity">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildUpdateSql"/>
+    </update>
+
+    <select id="query" parameterType="org.hswebframework.web.commons.entity.Entity" resultMap="OAuth2UserTokenResultMap">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildSelectSql"/>
+    </select>
+
+    <select id="count" parameterType="org.hswebframework.web.commons.entity.Entity" resultType="int">
+        <include refid="config"/>
+        <include refid="BasicMapper.buildTotalSql"/>
+    </select>
+</mapper>

+ 36 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-dao/pom.xml

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 
+  ~   Copyright 2016 http://www.hswebframework.org
+  ~  
+  ~   Licensed under the Apache License, Version 2.0 (the "License");
+  ~   you may not use this file except in compliance with the License.
+  ~   You may obtain a copy of the License at
+  ~  
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~  
+  ~   Unless required by applicable law or agreed to in writing, software
+  ~   distributed under the License is distributed on an "AS IS" BASIS,
+  ~   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~   See the License for the specific language governing permissions and
+  ~   limitations under the License.
+  ~  
+  -->
+
+<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-oauth2-client</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-dao</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>hsweb-system-oauth2-client-dao-api</module>
+        <module>hsweb-system-oauth2-client-dao-mybatis</module>
+    </modules>
+</project>

+ 40 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/pom.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 
+  ~   Copyright 2016 http://www.hswebframework.org
+  ~  
+  ~   Licensed under the Apache License, Version 2.0 (the "License");
+  ~   you may not use this file except in compliance with the License.
+  ~   You may obtain a copy of the License at
+  ~  
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~  
+  ~   Unless required by applicable law or agreed to in writing, software
+  ~   distributed under the License is distributed on an "AS IS" BASIS,
+  ~   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~   See the License for the specific language governing permissions and
+  ~   limitations under the License.
+  ~  
+  -->
+
+<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-oauth2-client</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-entity</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-entity</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+</project>

+ 155 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/OAuth2ServerConfigEntity.java

@@ -0,0 +1,155 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.entity.oauth2.client;
+
+import org.hswebframework.web.commons.entity.GenericEntity;
+
+/**
+ * OAuth2服务配置 实体
+ *
+ * @author hsweb-generator-online
+ */
+public interface OAuth2ServerConfigEntity extends GenericEntity<String> {
+ /*-------------------------------------------
+    |               属性名常量               |
+    ===========================================*/
+    /**
+     * 服务名称
+     */
+    String name           = "name";
+    /**
+     * 备注
+     */
+    String describe       = "describe";
+    /**
+     * api根地址
+     */
+    String apiBaseUrl     = "apiBaseUrl";
+    /**
+     * 认证地址
+     */
+    String authUrl        = "authUrl";
+    /**
+     * token获取地址
+     */
+    String accessTokenUrl = "accessTokenUrl";
+    /**
+     * 客户端id
+     */
+    String clientId       = "clientId";
+    /**
+     * 客户端密钥
+     */
+    String clientSecret   = "clientSecret";
+    /**
+     * 是否启用
+     */
+    String enabled        = "enabled";
+
+    String redirectUri = "redirectUri";
+
+    String provider = "provider";
+
+    String getProvider();
+
+    void setProvider(String provider);
+
+    String getRedirectUri();
+
+    void setRedirectUri(String redirectUri);
+
+    /**
+     * @return 服务名称
+     */
+    String getName();
+
+    /**
+     * 设置 服务名称
+     */
+    void setName(String name);
+
+    /**
+     * @return 备注
+     */
+    String getDescribe();
+
+    /**
+     * 设置 备注
+     */
+    void setDescribe(String describe);
+
+    /**
+     * @return api根地址
+     */
+    String getApiBaseUrl();
+
+    /**
+     * 设置 api根地址
+     */
+    void setApiBaseUrl(String apiBaseUrl);
+
+    /**
+     * @return 认证地址
+     */
+    String getAuthUrl();
+
+    /**
+     * 设置 认证地址
+     */
+    void setAuthUrl(String authUrl);
+
+    /**
+     * @return token获取地址
+     */
+    String getAccessTokenUrl();
+
+    /**
+     * 设置 token获取地址
+     */
+    void setAccessTokenUrl(String accessTokenUrl);
+
+    /**
+     * @return 客户端id
+     */
+    String getClientId();
+
+    /**
+     * 设置 客户端id
+     */
+    void setClientId(String clientId);
+
+    /**
+     * @return 客户端密钥
+     */
+    String getClientSecret();
+
+    /**
+     * 设置 客户端密钥
+     */
+    void setClientSecret(String clientSecret);
+
+    /**
+     * @return 是否启用
+     */
+    Boolean isEnabled();
+
+    /**
+     * 设置 是否启用
+     */
+    void setEnabled(Boolean enabled);
+
+}

+ 184 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/OAuth2UserTokenEntity.java

@@ -0,0 +1,184 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.entity.oauth2.client;
+
+import org.hswebframework.web.commons.entity.GenericEntity;
+
+/**
+ * OAuth2用户授权信息 实体
+ *
+ * @author hsweb-generator-online
+ */
+public interface OAuth2UserTokenEntity extends GenericEntity<String> {
+ /*-------------------------------------------
+    |               属性名常量               |
+    ===========================================*/
+    /**
+     * 客户端用户id
+     */
+    String clientUserId = "clientUserId";
+    /**
+     * 服务端用户id
+     */
+    String serverUserId = "serverUserId";
+    /**
+     * 服务端id
+     */
+    String serverId     = "serverId";
+    /**
+     * 客户端id
+     */
+    String clientId     = "clientId";
+    /**
+     * 授权码
+     */
+    String accessToken  = "accessToken";
+    /**
+     * 更新码
+     */
+    String refreshToken = "refreshToken";
+    /**
+     * 有效期
+     */
+    String expireIn     = "expireIn";
+    /**
+     * 授权范围
+     */
+    String scope        = "scope";
+    /**
+     * 创建时间
+     */
+    String createTime   = "createTime";
+    /**
+     * 更新时间
+     */
+    String updateTime   = "updateTime";
+
+    //授权方式
+    String grantType = "grantType";
+
+    /**
+     * @return 授权方式
+     */
+    String getGrantType();
+
+    /**
+     * 设置 授权方式
+     */
+    void setGrantType(String grantType);
+
+    /**
+     * @return 客户端用户id
+     */
+    String getClientUserId();
+
+    /**
+     * 设置 客户端用户id
+     */
+    void setClientUserId(String clientUserId);
+
+    /**
+     * @return 服务端用户id
+     */
+    String getServerUserId();
+
+    /**
+     * 设置 服务端用户id
+     */
+    void setServerUserId(String serverUserId);
+
+    /**
+     * @return 服务端id
+     */
+    String getServerId();
+
+    /**
+     * 设置 服务端id
+     */
+    void setServerId(String serverId);
+
+    /**
+     * @return 客户端id
+     */
+    String getClientId();
+
+    /**
+     * 设置 客户端id
+     */
+    void setClientId(String clientId);
+
+    /**
+     * @return 授权码
+     */
+    String getAccessToken();
+
+    /**
+     * 设置 授权码
+     */
+    void setAccessToken(String accessToken);
+
+    /**
+     * @return 更新码
+     */
+    String getRefreshToken();
+
+    /**
+     * 设置 更新码
+     */
+    void setRefreshToken(String refreshToken);
+
+    /**
+     * @return 有效期
+     */
+    Integer getExpiresIn();
+
+    /**
+     * 设置 有效期
+     */
+    void setExpiresIn(Integer expiresIn);
+
+    /**
+     * @return 授权范围
+     */
+    String getScope();
+
+    /**
+     * 设置 授权范围
+     */
+    void setScope(String scope);
+
+    /**
+     * @return 创建时间
+     */
+    Long getCreateTime();
+
+    /**
+     * 设置 创建时间
+     */
+    void setCreateTime(Long createTime);
+
+    /**
+     * @return 更新时间
+     */
+    Long getUpdateTime();
+
+    /**
+     * 设置 更新时间
+     */
+    void setUpdateTime(Long updateTime);
+
+}

+ 178 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/SimpleOAuth2ServerConfigEntity.java

@@ -0,0 +1,178 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.entity.oauth2.client;
+
+import org.hswebframework.web.commons.entity.SimpleGenericEntity;
+
+/**
+ * OAuth2服务配置
+ *
+ * @author hsweb-generator-online
+ */
+public class SimpleOAuth2ServerConfigEntity extends SimpleGenericEntity<String> implements OAuth2ServerConfigEntity {
+    //服务名称
+    private String  name;
+    //备注
+    private String  describe;
+    //api根地址
+    private String  apiBaseUrl;
+    //认证地址
+    private String  authUrl;
+    //token获取地址
+    private String  accessTokenUrl;
+    //客户端id
+    private String  clientId;
+    //客户端密钥
+    private String  clientSecret;
+    //是否启用
+    private Boolean enabled;
+    //重定向地址
+    private String  redirectUri;
+
+    //服务提供商
+    private String provider;
+
+    public String getProvider() {
+        return provider;
+    }
+
+    public void setProvider(String provider) {
+        this.provider = provider;
+    }
+
+    @Override
+    public String getRedirectUri() {
+        return redirectUri;
+    }
+
+    @Override
+    public void setRedirectUri(String redirectUri) {
+        this.redirectUri = redirectUri;
+    }
+
+    /**
+     * @return 服务名称
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * 设置 服务名称
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return 备注
+     */
+    public String getDescribe() {
+        return this.describe;
+    }
+
+    /**
+     * 设置 备注
+     */
+    public void setDescribe(String describe) {
+        this.describe = describe;
+    }
+
+    /**
+     * @return api根地址
+     */
+    public String getApiBaseUrl() {
+        return this.apiBaseUrl;
+    }
+
+    /**
+     * 设置 api根地址
+     */
+    public void setApiBaseUrl(String apiBaseUrl) {
+        this.apiBaseUrl = apiBaseUrl;
+    }
+
+    /**
+     * @return 认证地址
+     */
+    public String getAuthUrl() {
+        return this.authUrl;
+    }
+
+    /**
+     * 设置 认证地址
+     */
+    public void setAuthUrl(String authUrl) {
+        this.authUrl = authUrl;
+    }
+
+    /**
+     * @return token获取地址
+     */
+    public String getAccessTokenUrl() {
+        return this.accessTokenUrl;
+    }
+
+    /**
+     * 设置 token获取地址
+     */
+    public void setAccessTokenUrl(String accessTokenUrl) {
+        this.accessTokenUrl = accessTokenUrl;
+    }
+
+    /**
+     * @return 客户端id
+     */
+    public String getClientId() {
+        return this.clientId;
+    }
+
+    /**
+     * 设置 客户端id
+     */
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    /**
+     * @return 客户端密钥
+     */
+    public String getClientSecret() {
+        return this.clientSecret;
+    }
+
+    /**
+     * 设置 客户端密钥
+     */
+    public void setClientSecret(String clientSecret) {
+        this.clientSecret = clientSecret;
+    }
+
+    /**
+     * @return 是否启用
+     */
+    public Boolean isEnabled() {
+        return this.enabled;
+    }
+
+    /**
+     * 设置 是否启用
+     */
+    public void setEnabled(Boolean enabled) {
+        this.enabled = enabled;
+    }
+}

+ 199 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-entity/src/main/java/org/hswebframework/web/entity/oauth2/client/SimpleOAuth2UserTokenEntity.java

@@ -0,0 +1,199 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.entity.oauth2.client;
+
+import org.hswebframework.web.commons.entity.SimpleGenericEntity;
+
+/**
+ * OAuth2用户授权信息
+ *
+ * @author hsweb-generator-online
+ */
+public class SimpleOAuth2UserTokenEntity extends SimpleGenericEntity<String> implements OAuth2UserTokenEntity {
+    //客户端用户id
+    private String  clientUserId;
+    //服务端用户id
+    private String  serverUserId;
+    //服务端id
+    private String  serverId;
+    //客户端id
+    private String  clientId;
+    //授权码
+    private String  accessToken;
+    //更新码
+    private String  refreshToken;
+    //有效期
+    private Integer expiresIn;
+    //授权范围
+    private String  scope;
+    //创建时间
+    private Long    createTime;
+    //更新时间
+    private Long    updateTime;
+
+    private String grantType;
+
+    @Override
+    public String getGrantType() {
+        return grantType;
+    }
+
+    @Override
+    public void setGrantType(String grantType) {
+        this.grantType = grantType;
+    }
+
+    /**
+     * @return 客户端用户id
+     */
+    public String getClientUserId() {
+        return this.clientUserId;
+    }
+
+    /**
+     * 设置 客户端用户id
+     */
+    public void setClientUserId(String clientUserId) {
+        this.clientUserId = clientUserId;
+    }
+
+    /**
+     * @return 服务端用户id
+     */
+    public String getServerUserId() {
+        return this.serverUserId;
+    }
+
+    /**
+     * 设置 服务端用户id
+     */
+    public void setServerUserId(String serverUserId) {
+        this.serverUserId = serverUserId;
+    }
+
+    /**
+     * @return 服务端id
+     */
+    public String getServerId() {
+        return this.serverId;
+    }
+
+    /**
+     * 设置 服务端id
+     */
+    public void setServerId(String serverId) {
+        this.serverId = serverId;
+    }
+
+    /**
+     * @return 客户端id
+     */
+    public String getClientId() {
+        return this.clientId;
+    }
+
+    /**
+     * 设置 客户端id
+     */
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
+    /**
+     * @return 授权码
+     */
+    public String getAccessToken() {
+        return this.accessToken;
+    }
+
+    /**
+     * 设置 授权码
+     */
+    public void setAccessToken(String accessToken) {
+        this.accessToken = accessToken;
+    }
+
+    /**
+     * @return 更新码
+     */
+    public String getRefreshToken() {
+        return this.refreshToken;
+    }
+
+    /**
+     * 设置 更新码
+     */
+    public void setRefreshToken(String refreshToken) {
+        this.refreshToken = refreshToken;
+    }
+
+    /**
+     * @return 有效期
+     */
+    public Integer getExpiresIn() {
+        return this.expiresIn;
+    }
+
+    /**
+     * 设置 有效期
+     */
+    public void setExpiresIn(Integer expiresIn) {
+        this.expiresIn = expiresIn;
+    }
+
+    /**
+     * @return 授权范围
+     */
+    public String getScope() {
+        return this.scope;
+    }
+
+    /**
+     * 设置 授权范围
+     */
+    public void setScope(String scope) {
+        this.scope = scope;
+    }
+
+    /**
+     * @return 创建时间
+     */
+    public Long getCreateTime() {
+        return this.createTime;
+    }
+
+    /**
+     * 设置 创建时间
+     */
+    public void setCreateTime(Long createTime) {
+        this.createTime = createTime;
+    }
+
+    /**
+     * @return 更新时间
+     */
+    public Long getUpdateTime() {
+        return this.updateTime;
+    }
+
+    /**
+     * 设置 更新时间
+     */
+    public void setUpdateTime(Long updateTime) {
+        this.updateTime = updateTime;
+    }
+}

+ 42 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-api/pom.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+<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-oauth2-client-service</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-service-api</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-service-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-dao-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>

+ 29 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-api/src/main/java/org/hswebframework/web/service/oauth2.client/OAuth2ServerConfigService.java

@@ -0,0 +1,29 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.service.oauth2.client;
+
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+import org.hswebframework.web.service.CrudService;
+
+/**
+ *  OAuth2服务配置 服务类
+ *
+ * @author hsweb-generator-online
+ */
+public interface OAuth2ServerConfigService extends CrudService<OAuth2ServerConfigEntity, String> {
+
+}

+ 33 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-api/src/main/java/org/hswebframework/web/service/oauth2.client/OAuth2UserTokenService.java

@@ -0,0 +1,33 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.service.oauth2.client;
+
+import org.hswebframework.web.entity.oauth2.client.OAuth2UserTokenEntity;
+import org.hswebframework.web.service.CrudService;
+
+import java.util.List;
+
+/**
+ * OAuth2用户授权信息 服务类
+ *
+ * @author hsweb-generator-online
+ */
+public interface OAuth2UserTokenService extends CrudService<OAuth2UserTokenEntity, String> {
+    List<OAuth2UserTokenEntity> selectByServerIdAndGrantType(String serverId, String grantType);
+
+    OAuth2UserTokenEntity selectByAccessToken(String accessToken);
+}

+ 51 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/pom.xml

@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+<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-oauth2-client-service</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-service-simple</artifactId>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-commons-service-simple</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-service-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-authorization-oauth2-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework</groupId>
+            <artifactId>hsweb-expands-request</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 83 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2RequestService.java

@@ -0,0 +1,83 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple;
+
+import org.hswebframework.web.NotFoundException;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2RequestBuilderFactory;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2RequestService;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2SessionBuilder;
+import org.hswebframework.web.authorization.oauth2.client.listener.OAuth2Event;
+import org.hswebframework.web.authorization.oauth2.client.listener.OAuth2Listener;
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+import org.hswebframework.web.service.oauth2.client.OAuth2ServerConfigService;
+import org.hswebframework.web.service.oauth2.client.OAuth2UserTokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Service("oAuth2RequestService")
+public class SimpleOAuth2RequestService implements OAuth2RequestService {
+
+    private OAuth2ServerConfigService oAuth2ServerConfigService;
+
+    private OAuth2UserTokenService oAuth2UserTokenService;
+
+    private OAuth2RequestBuilderFactory oAuth2RequestBuilderFactory;
+
+    @Override
+    public OAuth2SessionBuilder create(String serverId) {
+        OAuth2ServerConfigEntity configEntity = oAuth2ServerConfigService.selectByPk(serverId);
+        if (null == configEntity || !Boolean.TRUE.equals(configEntity.isEnabled())) throw new NotFoundException("server not found!");
+        return new SimpleOAuth2SessionBuilder(oAuth2UserTokenService, configEntity, oAuth2RequestBuilderFactory);
+    }
+
+    @Override
+    public void registerListener(String serverId, OAuth2Listener<? extends OAuth2Event> listener) {
+
+    }
+
+    @Override
+    public void doEvent(String serverId, OAuth2Event event) {
+
+    }
+
+    @Override
+    public void doEvent(String serverId, OAuth2Event event, Class<? extends OAuth2Event> eventType) {
+
+    }
+
+    @Autowired
+    public void setoAuth2ServerConfigService(OAuth2ServerConfigService oAuth2ServerConfigService) {
+        this.oAuth2ServerConfigService = oAuth2ServerConfigService;
+    }
+
+    @Autowired
+    public void setoAuth2UserTokenService(OAuth2UserTokenService oAuth2UserTokenService) {
+        this.oAuth2UserTokenService = oAuth2UserTokenService;
+    }
+
+    @Autowired
+    public void setoAuth2RequestBuilderFactory(OAuth2RequestBuilderFactory oAuth2RequestBuilderFactory) {
+        this.oAuth2RequestBuilderFactory = oAuth2RequestBuilderFactory;
+    }
+}

+ 47 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2ServerConfigService.java

@@ -0,0 +1,47 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.service.oauth2.client.simple;
+
+import org.hswebframework.web.dao.oauth2.client.OAuth2ServerConfigDao;
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+import org.hswebframework.web.id.IDGenerator;
+import org.hswebframework.web.service.GenericEntityService;
+import org.hswebframework.web.service.oauth2.client.OAuth2ServerConfigService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 默认的服务实现
+ *
+ * @author hsweb-generator-online
+ */
+@Service("oAuth2ServerConfigService")
+public class SimpleOAuth2ServerConfigService extends GenericEntityService<OAuth2ServerConfigEntity, String>
+        implements OAuth2ServerConfigService {
+    @Autowired
+    private OAuth2ServerConfigDao oAuth2ServerConfigDao;
+   @Override
+    protected IDGenerator<String> getIDGenerator() {
+        return IDGenerator.MD5;
+    }
+
+    @Override
+    public OAuth2ServerConfigDao getDao() {
+        return oAuth2ServerConfigDao;
+    }
+
+}

+ 163 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2SessionBuilder.java

@@ -0,0 +1,163 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple;
+
+import org.hswebframework.web.NotFoundException;
+import org.hswebframework.web.authorization.oauth2.client.*;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Session;
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+import org.hswebframework.web.entity.oauth2.client.OAuth2UserTokenEntity;
+import org.hswebframework.web.service.oauth2.client.OAuth2UserTokenService;
+import org.hswebframework.web.service.oauth2.client.simple.session.AuthorizationCodeSession;
+import org.hswebframework.web.service.oauth2.client.simple.session.CachedOAuth2Session;
+import org.hswebframework.web.service.oauth2.client.simple.session.DefaultOAuth2Session;
+import org.hswebframework.web.service.oauth2.client.simple.session.PasswordSession;
+
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+
+/**
+ * @author zhouhao
+ */
+public class SimpleOAuth2SessionBuilder implements OAuth2SessionBuilder {
+    private OAuth2UserTokenService oAuth2UserTokenService;
+
+    private OAuth2ServerConfigEntity configEntity;
+
+    private OAuth2RequestBuilderFactory requestBuilderFactory;
+
+    public SimpleOAuth2SessionBuilder(OAuth2UserTokenService oAuth2UserTokenService,
+                                      OAuth2ServerConfigEntity oAuth2ServerConfig,
+                                      OAuth2RequestBuilderFactory requestBuilderFactory) {
+        this.oAuth2UserTokenService = oAuth2UserTokenService;
+        this.configEntity = oAuth2ServerConfig;
+        this.requestBuilderFactory = requestBuilderFactory;
+    }
+
+    protected String getRealUrl(String url) {
+        if (url.startsWith("http")) return url;
+        if (!configEntity.getApiBaseUrl().endsWith("/") && !url.startsWith("/"))
+            return configEntity.getApiBaseUrl().concat("/").concat(url);
+        return configEntity.getApiBaseUrl() + url;
+    }
+
+    private void token2entity(AccessTokenInfo token, OAuth2UserTokenEntity entity) {
+        entity.setAccessToken(token.getAccessToken());
+        entity.setRefreshToken(token.getRefreshToken());
+        entity.setExpiresIn(token.getExpiresIn());
+        entity.setScope(token.getScope());
+        entity.setCreateTime(token.getCreateTime());
+        entity.setUpdateTime(token.getUpdateTime());
+    }
+
+    private void entity2token(OAuth2UserTokenEntity entity, AccessTokenInfo token) {
+        token.setAccessToken(entity.getAccessToken());
+        token.setRefreshToken(entity.getRefreshToken());
+        token.setExpiresIn(entity.getExpiresIn());
+        token.setScope(entity.getScope());
+        token.setCreateTime(entity.getCreateTime());
+        token.setUpdateTime(entity.getUpdateTime());
+    }
+
+
+    protected OAuth2UserTokenEntity getClientCredentialsToken() {
+        List<OAuth2UserTokenEntity> list = oAuth2UserTokenService
+                .selectByServerIdAndGrantType(configEntity.getId(), GrantType.client_credentials);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    protected Consumer<AccessTokenInfo> createOnTokenChanged(Supplier<OAuth2UserTokenEntity> tokenGetter, String grantType) {
+        return token -> {
+            OAuth2UserTokenEntity tokenEntity = tokenGetter.get();
+            if (tokenEntity != null) {
+                tokenEntity.setUpdateTime(System.currentTimeMillis());
+                token2entity(token, tokenEntity);
+                oAuth2UserTokenService.updateByPk(tokenEntity.getId(), tokenEntity);
+            } else {
+                tokenEntity = oAuth2UserTokenService.createEntity();
+                tokenEntity.setGrantType(grantType);
+                tokenEntity.setCreateTime(System.currentTimeMillis());
+                tokenEntity.setServerId(configEntity.getId());
+                token2entity(token, tokenEntity);
+                oAuth2UserTokenService.insert(tokenEntity);
+            }
+        };
+    }
+
+    private final Consumer<AccessTokenInfo> onClientCredentialsTokenChanged = createOnTokenChanged(this::getClientCredentialsToken, GrantType.client_credentials);
+
+    @Override
+    public OAuth2Session byAuthorizationCode(String code) {
+        AuthorizationCodeSession authorizationCodeSession = new AuthorizationCodeSession();
+        authorizationCodeSession.setCode(code);
+        authorizationCodeSession.setRequestBuilderFactory(requestBuilderFactory);
+        authorizationCodeSession.setConfigEntity(configEntity);
+        authorizationCodeSession.init();
+        return authorizationCodeSession;
+    }
+
+
+    @Override
+    public OAuth2Session byClientCredentials() {
+        OAuth2UserTokenEntity entity = getClientCredentialsToken();
+        DefaultOAuth2Session session;
+        if (null != entity) {
+            AccessTokenInfo tokenInfo = new AccessTokenInfo();
+            entity2token(entity, tokenInfo);
+            session = new CachedOAuth2Session(tokenInfo);
+        } else {
+            session = new DefaultOAuth2Session();
+        }
+        session.setConfigEntity(configEntity);
+        session.setRequestBuilderFactory(requestBuilderFactory);
+        session.onTokenChanged(onClientCredentialsTokenChanged);
+        session.init();
+        session.param(OAuth2Constants.grant_type, GrantType.client_credentials);
+        return session;
+    }
+
+    @Override
+    public OAuth2Session byPassword(String username, String password) {
+        PasswordSession session = new PasswordSession(username, password);
+        session.setConfigEntity(configEntity);
+        session.setRequestBuilderFactory(requestBuilderFactory);
+        session.init();
+        return session;
+    }
+
+    @Override
+    public OAuth2Session byAccessToken(String accessToken) {
+        Supplier<OAuth2UserTokenEntity> supplier = () -> oAuth2UserTokenService.selectByAccessToken(accessToken);
+        OAuth2UserTokenEntity tokenEntity = supplier.get();
+        if (tokenEntity == null) throw new NotFoundException("access_token not found");
+
+        AccessTokenInfo tokenInfo = new AccessTokenInfo();
+        entity2token(tokenEntity, tokenInfo);
+        CachedOAuth2Session session = new CachedOAuth2Session(tokenInfo);
+        session.setConfigEntity(configEntity);
+        session.setRequestBuilderFactory(requestBuilderFactory);
+        session.onTokenChanged(createOnTokenChanged(supplier, null));
+        session.init();
+        return session;
+    }
+
+
+}

+ 70 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/SimpleOAuth2UserTokenService.java

@@ -0,0 +1,70 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *  
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  
+ */
+package org.hswebframework.web.service.oauth2.client.simple;
+
+import org.hswebframework.web.dao.oauth2.client.OAuth2UserTokenDao;
+import org.hswebframework.web.entity.oauth2.client.OAuth2UserTokenEntity;
+import org.hswebframework.web.id.IDGenerator;
+import org.hswebframework.web.service.GenericEntityService;
+import org.hswebframework.web.service.oauth2.client.OAuth2UserTokenService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import java.util.List;
+
+/**
+ * 默认的服务实现
+ *
+ * @author hsweb-generator-online
+ */
+@Service("oAuth2UserTokenService")
+public class SimpleOAuth2UserTokenService extends GenericEntityService<OAuth2UserTokenEntity, String>
+        implements OAuth2UserTokenService {
+    @Autowired
+    private OAuth2UserTokenDao oAuth2UserTokenDao;
+
+    @Override
+    protected IDGenerator<String> getIDGenerator() {
+        return IDGenerator.MD5;
+    }
+
+    @Override
+    public OAuth2UserTokenDao getDao() {
+        return oAuth2UserTokenDao;
+    }
+
+    @Override
+    @Cacheable(cacheNames = "oauth2-user-token", key = "'s-g-t:'+#serverId+':'+#grantType")
+    public List<OAuth2UserTokenEntity> selectByServerIdAndGrantType(String serverId, String grantType) {
+        Assert.notNull(serverId, "serverId can not be null!");
+        Assert.notNull(grantType, "grantType can not be null!");
+        return createQuery()
+                .where(OAuth2UserTokenEntity.serverId, serverId)
+                .is(OAuth2UserTokenEntity.grantType, grantType)
+                .listNoPaging();
+    }
+
+    @Override
+    @Cacheable(cacheNames = "oauth2-user-token", key = "'a-t:'+#serverId+':'+#grantType")
+    public OAuth2UserTokenEntity selectByAccessToken(String accessToken) {
+        Assert.notNull(accessToken, "token can not be null!");
+        return createQuery().where(OAuth2UserTokenEntity.accessToken, accessToken)
+                .single();
+    }
+}

+ 34 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/ResponseConvertHandler.java

@@ -0,0 +1,34 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request;
+
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface ResponseConvertHandler {
+    <T> T convert(OAuth2Response response, Class<T> type);
+
+    <T> List<T> convertList(OAuth2Response response, Class<T> type);
+}

+ 28 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/ResponseJudge.java

@@ -0,0 +1,28 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request;
+
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+
+/**
+ * @author zhouhao
+ */
+public interface ResponseJudge {
+    OAuth2Response.ErrorType judge(OAuth2Response response);
+}

+ 150 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/SimpleOAuth2Request.java

@@ -0,0 +1,150 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request;
+
+import org.hswebframework.expands.request.http.HttpRequest;
+import org.hswebframework.expands.request.http.Response;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Request;
+import org.hswebframework.web.authorization.oauth2.client.request.TokenExpiredCallBack;
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * @author zhouhao
+ */
+public class SimpleOAuth2Request implements OAuth2Request {
+
+    private HttpRequest request;
+
+    private ResponseConvertHandler convertHandler;
+
+    private ResponseJudge responseJudge;
+
+    private TokenExpiredCallBack expiredCallBack;
+
+    public SimpleOAuth2Request(HttpRequest request) {
+        this.request = request;
+    }
+
+    public void setConvertHandler(ResponseConvertHandler convertHandler) {
+        this.convertHandler = convertHandler;
+    }
+
+    public void setResponseJudge(ResponseJudge responseJudge) {
+        this.responseJudge = responseJudge;
+    }
+
+    @Override
+    public OAuth2Request onTokenExpired(TokenExpiredCallBack callback) {
+        this.expiredCallBack = callback;
+        return this;
+    }
+
+    @Override
+    public OAuth2Request param(String name, Object value) {
+        request.param(name, String.valueOf(value));
+        return this;
+    }
+
+    @Override
+    public OAuth2Request requestBody(String value) {
+        request.requestBody(value);
+        return this;
+    }
+
+    @Override
+    public OAuth2Request header(String name, String value) {
+        request.header(name, value);
+        return this;
+    }
+
+    @Override
+    public OAuth2Request cookie(String cookie) {
+        request.cookie(cookie);
+        return this;
+    }
+
+    @Override
+    public OAuth2Request contentType(String contentType) {
+        request.contentType(contentType);
+        return this;
+    }
+
+    @Override
+    public OAuth2Request accept(String accept) {
+        header("Accept", accept);
+        return this;
+    }
+
+    @Override
+    public OAuth2Request timeout(long millisecond, Consumer<OAuth2Request> timeoutCallBack) {
+        return this;
+    }
+
+    private volatile SimpleOAuth2Response auth2Response;
+
+    protected SimpleOAuth2Response createNativeResponse(Supplier<Response> responseSupplier) {
+        return auth2Response = new SimpleOAuth2Response(responseSupplier.get(), convertHandler, responseJudge);
+    }
+
+    protected OAuth2Response createResponse(Supplier<Response> responseSupplier) {
+        createNativeResponse(responseSupplier);
+        if (null != expiredCallBack) {
+            //判定token是否过期,过期后先执行回调进行操作如更新token,并尝试重新请求
+            auth2Response.judgeExpired(() -> {
+                //调用回调,并指定重试的操作(重新请求)
+                expiredCallBack.call(() -> createNativeResponse(responseSupplier));
+                //返回重试后的response
+                return auth2Response;
+            });
+        }
+        return auth2Response;
+    }
+
+    protected OAuth2Response createUnCheckResponse(UnCheck<Response> unCheck) {
+        return createResponse(() -> UnCheck.unCheck(unCheck));
+    }
+
+    @Override
+    public OAuth2Response get() {
+        return createUnCheckResponse(request::get);
+    }
+
+    @Override
+    public OAuth2Response put() {
+        return createUnCheckResponse(request::put);
+    }
+
+    @Override
+    public OAuth2Response post() {
+        return createUnCheckResponse(request::post);
+    }
+
+    @Override
+    public OAuth2Response delete() {
+        return createUnCheckResponse(request::delete);
+    }
+
+    @Override
+    public OAuth2Response patch() {
+        return createUnCheckResponse(request::patch);
+    }
+}

+ 115 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/SimpleOAuth2Response.java

@@ -0,0 +1,115 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request;
+
+import org.hswebframework.expands.request.http.Response;
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+import org.hswebframework.web.authorization.oauth2.client.response.ResponseConvert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.Supplier;
+
+/**
+ * @author zhouhao
+ */
+public class SimpleOAuth2Response implements OAuth2Response {
+
+    private ResponseConvertHandler convertHandler;
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private ErrorType errorType;
+
+    private byte[] data;
+
+    private int status;
+
+    private OAuth2Response proxy = this;
+
+    public void judgeExpired(Supplier<OAuth2Response> expiredCallBack) {
+        if (errorType == ErrorType.EXPIRED_TOKEN) {
+            //尝试执行认证过时回调进行重试,并返回重试的结果
+            OAuth2Response retryRes = expiredCallBack.get();
+            if (retryRes == null) return;
+            proxy = retryRes;
+            proxy.onError((retryResponse, type) -> {
+                if (type == ErrorType.EXPIRED_TOKEN) {
+                    //重试后依然是认证过时,可能是错误类型判断错误或者服务端的问题?
+                    logger.warn("still error [expired_token], maybe judge error or auth server error! ");
+                } else {
+                    errorType = type;
+                }
+            });
+            data = UnCheck.unCheck(proxy::asBytes);
+            status = proxy.status();
+        }
+    }
+
+    public SimpleOAuth2Response(Response response,
+                                ResponseConvertHandler convertHandler,
+                                ResponseJudge responseJudge) {
+        this.convertHandler = convertHandler;
+        data = UnCheck.unCheck(response::asBytes);
+        status = response.getCode();
+        errorType = responseJudge.judge(this);
+    }
+
+    @Override
+    public String asString() {
+        if (asBytes() == null) return null;
+        return new String(asBytes());
+    }
+
+    @Override
+    public byte[] asBytes() {
+        return data;
+    }
+
+    @Override
+    public <T> T as(ResponseConvert<T> convert) {
+        return convert.convert(this);
+    }
+
+    @Override
+    public <T> T as(Class<T> type) {
+        return convertHandler.convert(this, type);
+    }
+
+    @Override
+    public <T> List<T> asList(Class<T> type) {
+        return convertHandler.convertList(this, type);
+    }
+
+    @Override
+    public int status() {
+        return status;
+    }
+
+    @Override
+    public OAuth2Response onError(BiConsumer<OAuth2Response, ErrorType> onError) {
+        if (null != errorType) {
+            onError.accept(proxy, errorType);
+        }
+        return proxy;
+    }
+
+}

+ 31 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/UnCheck.java

@@ -0,0 +1,31 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request;
+
+interface UnCheck<T> {
+        T call() throws Exception;
+
+        static <T> T unCheck(UnCheck<T> unCheck) {
+            try {
+                return unCheck.call();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }

+ 69 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/builder/SimpleOAuth2RequestBuilder.java

@@ -0,0 +1,69 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request.builder;
+
+import org.hswebframework.expands.request.RequestBuilder;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2RequestBuilder;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Request;
+import org.hswebframework.web.service.oauth2.client.simple.request.ResponseConvertHandler;
+import org.hswebframework.web.service.oauth2.client.simple.request.ResponseJudge;
+import org.hswebframework.web.service.oauth2.client.simple.request.SimpleOAuth2Request;
+
+/**
+ * @author zhouhao
+ */
+public class SimpleOAuth2RequestBuilder implements OAuth2RequestBuilder {
+
+    private RequestBuilder requestBuilder;
+
+    private String url;
+
+    private ResponseConvertHandler convertHandler;
+
+    private ResponseJudge responseJudge;
+
+    public SimpleOAuth2RequestBuilder requestBuilder(RequestBuilder requestBuilder) {
+        this.requestBuilder = requestBuilder;
+        return this;
+    }
+
+    public SimpleOAuth2RequestBuilder convertHandler(ResponseConvertHandler convertHandler) {
+        this.convertHandler = convertHandler;
+        return this;
+    }
+
+    public SimpleOAuth2RequestBuilder responseJudge(ResponseJudge responseJudge) {
+        this.responseJudge = responseJudge;
+        return this;
+    }
+
+    @Override
+    public SimpleOAuth2RequestBuilder url(String url) {
+        this.url = url;
+        return this;
+    }
+
+    @Override
+    public OAuth2Request build() {
+        SimpleOAuth2Request request = new SimpleOAuth2Request(url.startsWith("https:") ? requestBuilder.https(url) : requestBuilder.http(url));
+        request.setConvertHandler(convertHandler);
+        request.setResponseJudge(responseJudge);
+        return request;
+    }
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 130 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/builder/SimpleOAuth2RequestBuilderFactory.java


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 30 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseConvertForProviderDefinition.java


+ 30 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseConvertForServerIdDefinition.java

@@ -0,0 +1,30 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request.definition;
+
+import org.hswebframework.web.service.oauth2.client.simple.request.ResponseConvertHandler;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface ResponseConvertForServerIdDefinition extends ResponseConvertHandler {
+    String getServerId();
+}

+ 29 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseJudgeForProviderDefinition.java

@@ -0,0 +1,29 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request.definition;
+
+import org.hswebframework.web.service.oauth2.client.simple.request.ResponseJudge;
+
+/**
+ *
+ * @author zhouhao
+ */
+public interface ResponseJudgeForProviderDefinition extends ResponseJudge {
+    String getProvider();
+}

+ 30 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/request/definition/ResponseJudgeForServerIdDefinition.java

@@ -0,0 +1,30 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.request.definition;
+
+import org.hswebframework.web.service.oauth2.client.simple.request.ResponseJudge;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public interface ResponseJudgeForServerIdDefinition extends ResponseJudge {
+    String getServerId();
+}

+ 54 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/AuthorizationCodeSession.java

@@ -0,0 +1,54 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.session;
+
+import org.hswebframework.web.authorization.oauth2.client.GrantType;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2Constants;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Request;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Session;
+
+/**
+ * @author zhouhao
+ */
+public class AuthorizationCodeSession extends DefaultOAuth2Session {
+    private String code;
+
+    private boolean init = false;
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    @Override
+    protected void applyBasicAuthParam(OAuth2Request request) {
+        super.applyBasicAuthParam(request);
+        request.param(OAuth2Constants.grant_type, GrantType.authorization_code);
+    }
+
+    @Override
+    public OAuth2Session authorize() {
+        if (init) {
+            throw new UnsupportedOperationException("AuthorizationCode模式不能重复连接");
+        }
+        accessTokenRequest.param("code", code);
+        super.authorize();
+        init = true;
+        return this;
+    }
+}

+ 40 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/CachedOAuth2Session.java

@@ -0,0 +1,40 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.session;
+
+import org.hswebframework.web.authorization.oauth2.client.AccessTokenInfo;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Session;
+
+/**
+ *
+ * @author zhouhao
+ */
+public class CachedOAuth2Session extends DefaultOAuth2Session {
+
+
+    public CachedOAuth2Session(AccessTokenInfo tokenInfo) {
+        super.accessTokenInfo = tokenInfo;
+    }
+
+    @Override
+    public OAuth2Session authorize() {
+        // do no thing
+        return this;
+    }
+}

+ 178 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/DefaultOAuth2Session.java

@@ -0,0 +1,178 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.session;
+
+import org.apache.commons.codec.binary.Base64;
+import org.hswebframework.web.authorization.oauth2.client.AccessTokenInfo;
+import org.hswebframework.web.authorization.oauth2.client.GrantType;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2Constants;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2RequestBuilderFactory;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Request;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Session;
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+import org.springframework.util.Assert;
+
+import java.util.function.Consumer;
+
+import static org.hswebframework.web.authorization.oauth2.client.OAuth2Constants.*;
+
+/**
+ * @author zhouhao
+ */
+public class DefaultOAuth2Session implements OAuth2Session {
+
+    protected OAuth2RequestBuilderFactory requestBuilderFactory;
+
+    protected OAuth2ServerConfigEntity configEntity;
+
+    protected boolean closed = false;
+
+    protected OAuth2Request accessTokenRequest;
+
+    protected AccessTokenInfo accessTokenInfo;
+
+    protected String scope;
+
+    private Consumer<AccessTokenInfo> onTokenChange;
+
+    public void setRequestBuilderFactory(OAuth2RequestBuilderFactory requestBuilderFactory) {
+        this.requestBuilderFactory = requestBuilderFactory;
+    }
+
+    public void setConfigEntity(OAuth2ServerConfigEntity configEntity) {
+        this.configEntity = configEntity;
+    }
+
+    public void init() {
+        Assert.notNull(requestBuilderFactory, "requestBuilderFactory can not be null!");
+        Assert.notNull(configEntity, "configEntity can not be null!");
+        accessTokenRequest = createRequest(configEntity.getAccessTokenUrl());
+        applyBasicAuthParam(accessTokenRequest);
+    }
+
+    protected OAuth2Request createRequest(String uriOrUrl) {
+        return requestBuilderFactory
+                .create(configEntity.getId(), configEntity.getProvider())
+                .url(getRealUrl(uriOrUrl))
+                .build();
+    }
+
+    public void onTokenChanged(Consumer<AccessTokenInfo> changed) {
+        onTokenChange = changed;
+    }
+
+    protected String encodeAuthorization(String auth) {
+        String code = "basic ".concat(auth);
+        return Base64.encodeBase64String(code.getBytes());
+    }
+
+    protected void applyBasicAuthParam(OAuth2Request request) {
+        request.param(client_id, configEntity.getClientId());
+        request.param(client_secret, configEntity.getClientSecret());
+
+        request.header(authorization, encodeAuthorization(configEntity.getClientId().concat(":").concat(configEntity.getClientSecret())));
+    }
+
+    protected void applyTokenParam(OAuth2Request request) {
+        request.param(access_token, getAccessToken().getAccessToken());
+        request.header(authorization, "Bearer " + getAccessToken().getAccessToken());
+    }
+
+    protected String getRealUrl(String url) {
+        if (url.startsWith("http")) return url;
+        if (!configEntity.getApiBaseUrl().endsWith("/") && !url.startsWith("/"))
+            return configEntity.getApiBaseUrl().concat("/").concat(url);
+        return configEntity.getApiBaseUrl() + url;
+    }
+
+    @Override
+    public OAuth2Session authorize() {
+        AccessTokenInfo accessTokenInfo = accessTokenRequest
+                .param(OAuth2Constants.scope, scope)
+                .post().onError(OAuth2Response.throwOnError)
+                .as(AccessTokenInfo.class);
+        accessTokenInfo.setCreateTime(System.currentTimeMillis());
+        setAccessTokenInfo(accessTokenInfo);
+        return this;
+    }
+
+    @Override
+    public OAuth2Request request(String uriOrUrl) {
+        if (accessTokenInfo == null) authorize();
+        OAuth2Request request = createRequest(getRealUrl(uriOrUrl));
+        request.onTokenExpired(retry -> {
+            refreshToken(); //刷新token
+            applyTokenParam(request); //重设请求参数
+            retry.doReTry(); //执行重试
+        });
+        applyTokenParam(request);
+        return request;
+    }
+
+    @Override
+    public OAuth2Session param(String name, Object value) {
+        accessTokenRequest.param(name, String.valueOf(value));
+        return this;
+    }
+
+    protected void refreshToken() {
+        if (accessTokenInfo == null) return;
+        OAuth2Request request = createRequest(getRealUrl(configEntity.getAccessTokenUrl()));
+        applyBasicAuthParam(request);
+        AccessTokenInfo tokenInfo = request
+                .param(OAuth2Constants.scope, scope)
+                .param(OAuth2Constants.grant_type, GrantType.refresh_token)
+                .param(GrantType.refresh_token, accessTokenInfo.getRefreshToken())
+                .post().onError(OAuth2Response.throwOnError)
+                .as(AccessTokenInfo.class);
+        tokenInfo.setCreateTime(accessTokenInfo.getCreateTime());
+        tokenInfo.setUpdateTime(System.currentTimeMillis());
+        setAccessTokenInfo(tokenInfo);
+    }
+
+
+    @Override
+    public OAuth2Session scope(String scope) {
+        this.scope = scope;
+        return this;
+    }
+
+    @Override
+    public void close() {
+        closed = true;
+    }
+
+    @Override
+    public boolean isClosed() {
+        return closed;
+    }
+
+    @Override
+    public AccessTokenInfo getAccessToken() {
+        if (accessTokenInfo == null) return null;
+        if (accessTokenInfo.isExpire()) refreshToken();
+        return accessTokenInfo;
+    }
+
+    private void setAccessTokenInfo(AccessTokenInfo accessTokenInfo) {
+        this.accessTokenInfo = accessTokenInfo;
+        if (onTokenChange != null) onTokenChange.accept(accessTokenInfo);
+    }
+}

+ 46 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/hsweb-system-oauth2-client-service-simple/src/main/java/org/hswebframework/web/service/oauth2/client/simple/session/PasswordSession.java

@@ -0,0 +1,46 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.simple.session;
+
+import org.hswebframework.web.authorization.oauth2.client.GrantType;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2Constants;
+import org.hswebframework.web.authorization.oauth2.client.request.OAuth2Request;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class PasswordSession extends DefaultOAuth2Session {
+    String username;
+    String password;
+
+    public PasswordSession(String username, String password) {
+        this.username = username;
+        this.password = password;
+    }
+
+    @Override
+    protected void applyBasicAuthParam(OAuth2Request request) {
+        request.param(OAuth2Constants.grant_type, GrantType.password);
+        request.param("username", username);
+        request.param("password", configEntity.getClientSecret());
+        request.header(OAuth2Constants.authorization, encodeAuthorization(username.concat(":").concat(password)));
+    }
+}

+ 34 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-service/pom.xml

@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+<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-oauth2-client</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-service</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>hsweb-system-oauth2-client-service-api</module>
+        <module>hsweb-system-oauth2-client-service-simple</module>
+    </modules>
+</project>

+ 91 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/pom.xml

@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2016 http://www.hswebframework.org
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~       http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~  See the License for the specific language governing permissions and
+  ~  limitations under the License.
+  ~
+  -->
+
+<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-oauth2-client</artifactId>
+        <groupId>org.hswebframework.web</groupId>
+        <version>3.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>hsweb-system-oauth2-client-starter</artifactId>
+
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-service-simple</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-dao-mybatis</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hswebframework.web</groupId>
+            <artifactId>hsweb-system-oauth2-client-controller</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid</artifactId>
+            <version>1.0.26</version>
+            <scope>test</scope>
+        </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>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

+ 46 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/main/java/org/hswebframework/web/service/oauth2/client/starter/DefaultResponseJudge.java

@@ -0,0 +1,46 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.starter;
+
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+import org.hswebframework.web.service.oauth2.client.simple.request.ResponseJudge;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+public class DefaultResponseJudge implements ResponseJudge {
+    private static List<OAuth2Response.ErrorType> errorTypes = Arrays.stream(OAuth2Response.ErrorType.values())
+            .filter(errorType -> errorType != OAuth2Response.ErrorType.OTHER)
+            .collect(Collectors.toList());
+
+    @Override
+    public OAuth2Response.ErrorType judge(OAuth2Response response) {
+        if (response.status() == 200) return null;
+        String result = response.asString();
+        if (result == null) return OAuth2Response.ErrorType.OTHER;
+        return errorTypes.stream()
+                .filter(errorType -> result.contains(errorType.name().toLowerCase()))
+                .findAny().orElse(null);
+    }
+}

+ 52 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/main/java/org/hswebframework/web/service/oauth2/client/starter/OAuth2ClientAutoConfiguration.java

@@ -0,0 +1,52 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.service.oauth2.client.starter;
+
+import org.hswebframework.expands.request.RequestBuilder;
+import org.hswebframework.expands.request.SimpleRequestBuilder;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2RequestBuilderFactory;
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+import org.hswebframework.web.service.oauth2.client.simple.request.builder.SimpleOAuth2RequestBuilderFactory;
+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.Conditional;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author zhouhao
+ */
+@Configuration
+@ConditionalOnMissingBean(OAuth2RequestBuilderFactory.class)
+public class OAuth2ClientAutoConfiguration {
+
+    @Bean
+    @ConditionalOnMissingBean(RequestBuilder.class)
+    public RequestBuilder requestBuilder() {
+        return new SimpleRequestBuilder();
+    }
+
+    @Bean
+    public SimpleOAuth2RequestBuilderFactory simpleOAuth2RequestBuilderFactory(RequestBuilder requestBuilder) {
+        SimpleOAuth2RequestBuilderFactory builderFactory = new SimpleOAuth2RequestBuilderFactory();
+        builderFactory.setRequestBuilder(requestBuilder);
+        builderFactory.setDefaultResponseJudge(new DefaultResponseJudge());
+        return builderFactory;
+    }
+}

+ 82 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/main/resources/hsweb-starter.js

@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 http://www.hswebframework.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+//组件信息
+var info = {
+    groupId: "${project.groupId}",
+    artifactId: "${project.artifactId}",
+    version: "${project.version}",
+    website: "https://github.com/hs-web/hsweb-framework/tree/master/hsweb-system/hsweb-system-oauth2-client",
+    author: "zh.sqy@qq.com",
+    comment: "OAuth2服务配置"
+};
+
+//版本更新信息
+var versions = [
+    // {
+    //     version: "3.0.0",
+    //     upgrade: function (context) {
+    //         java.lang.System.out.println("更新到3.0.2了");
+    //     }
+    // }
+];
+var JDBCType = java.sql.JDBCType;
+function install(context) {
+    var database = context.database;
+    database.createOrAlter("s_oauth2_server")
+        .addColumn().name("u_id").alias("id").comment("ID").jdbcType(java.sql.JDBCType.VARCHAR).length(32).primaryKey().commit()
+        .addColumn().name("name").alias("name").comment("服务名称").jdbcType(java.sql.JDBCType.VARCHAR).length(32).commit()
+        .addColumn().name("describe").alias("describe").comment("备注").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .addColumn().name("api_base_url").alias("apiBaseUrl").comment("api根地址").jdbcType(java.sql.JDBCType.VARCHAR).length(512).commit()
+        .addColumn().name("auth_url").alias("authUrl").comment("认证地址").jdbcType(java.sql.JDBCType.VARCHAR).length(512).commit()
+        .addColumn().name("redirect_uri").alias("redirectUri").comment("重定向地址").jdbcType(java.sql.JDBCType.VARCHAR).length(512).commit()
+        .addColumn().name("access_token_url").alias("accessTokenUrl").comment("token获取地址").jdbcType(java.sql.JDBCType.VARCHAR).length(512).commit()
+        .addColumn().name("client_id").alias("clientId").comment("客户端id").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .addColumn().name("client_secret").alias("clientSecret").comment("客户端密钥").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .addColumn().name("provider").alias("provider").comment("服务提供商").jdbcType(java.sql.JDBCType.VARCHAR).length(32).commit()
+        .addColumn().name("properties").alias("properties").comment("其他配置").jdbcType(java.sql.JDBCType.CLOB).commit()
+        .addColumn().name("enabled").alias("enabled").comment("是否启用").jdbcType(java.sql.JDBCType.DECIMAL).length(4, 0).commit()
+        .comment("OAuth2 服务配置").commit();
+
+    database.createOrAlter("s_oauth2_user_token")
+        .addColumn().name("u_id").alias("id").comment("ID").jdbcType(java.sql.JDBCType.VARCHAR).length(32).primaryKey().commit()
+        .addColumn().name("client_user_id").alias("clientUserId").comment("客户端用户id").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .addColumn().name("server_user_id").alias("serverUserId").comment("服务端用户id").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .addColumn().name("server_id").alias("serverId").comment("服务端id").jdbcType(java.sql.JDBCType.VARCHAR).length(32).commit()
+        .addColumn().name("client_id").alias("clientId").comment("客户端id").jdbcType(java.sql.JDBCType.VARCHAR).length(32).commit()
+        .addColumn().name("access_token").alias("accessToken").comment("授权码").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .addColumn().name("refresh_token").alias("refreshToken").comment("更新码").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .addColumn().name("expires_in").alias("expireIn").comment("有效期").jdbcType(java.sql.JDBCType.DECIMAL).length(32, 0).commit()
+        .addColumn().name("scope").alias("scope").comment("授权范围").jdbcType(java.sql.JDBCType.CLOB).commit()
+        .addColumn().name("create_time").alias("createTime").comment("创建时间").jdbcType(java.sql.JDBCType.DECIMAL).length(32, 0).commit()
+        .addColumn().name("update_time").alias("updateTime").comment("更新时间").jdbcType(java.sql.JDBCType.DECIMAL).length(32, 0).commit()
+        .addColumn().name("grant_type").alias("grant_type").comment("授权方式").jdbcType(java.sql.JDBCType.VARCHAR).length(128).commit()
+        .comment("OAuth2用户授权信息").commit();
+}
+
+//设置依赖
+dependency.setup(info)
+    .onInstall(install)
+    .onUpgrade(function (context) { //更新时执行
+        var upgrader = context.upgrader;
+        upgrader.filter(versions)
+            .upgrade(function (newVer) {
+                newVer.upgrade(context);
+            });
+    })
+    .onUninstall(function (context) { //卸载时执行
+
+    });

+ 123 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/java/org/hswebframework/web/starter/oauth2/client/OAuth2ServerConfigTests.java

@@ -0,0 +1,123 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.starter.oauth2.client;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.hswebframework.web.authorization.oauth2.client.OAuth2RequestService;
+import org.hswebframework.web.authorization.oauth2.client.exception.OAuth2RequestException;
+import org.hswebframework.web.entity.oauth2.client.OAuth2ServerConfigEntity;
+import org.hswebframework.web.starter.convert.FastJsonHttpMessageConverter;
+import org.hswebframework.web.tests.SimpleWebApplicationTests;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+
+import java.util.Map;
+
+/**
+ * TODO 完善单元测试
+ *
+ * @author hsweb-generator-online
+ */
+public class OAuth2ServerConfigTests extends SimpleWebApplicationTests {
+
+    @Autowired
+    private FastJsonHttpMessageConverter fastJsonHttpMessageConverter;
+
+
+    @Autowired
+    private OAuth2RequestService oAuth2RequestService;
+
+    @Test
+    public void testOAuth2() throws Exception {
+        OAuth2ServerConfigEntity entity = entityFactory.newInstance(OAuth2ServerConfigEntity.class);
+        //https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=123&redirect_uri=www.baidu.com
+        entity.setId("my_qq_test");
+        entity.setName("QQ OAuth2");
+        entity.setApiBaseUrl("https://graph.qq.com/oauth2.0/");
+        entity.setAuthUrl("authorize");
+        entity.setAccessTokenUrl("token");
+        entity.setClientId("911ab25b8a87684beba8f394f47d3de9");
+        entity.setClientSecret("2cce659031d5e1495e102be0de9e9cb0");
+        entity.setRedirectUri("http://demo.hsweb.me");
+        entity.setProvider("QQ");
+        entity.setEnabled(true);
+        //add
+        String requestBody = JSON.toJSONString(entity);
+        JSONObject result = testPost("/oauth2-server-config")
+                .setUp(setup -> setup.contentType(MediaType.APPLICATION_JSON)
+                        .content(requestBody)).exec().resultAsJson();
+        Assert.assertEquals(200, result.get("status"));
+
+        try {
+            Map meInfo = oAuth2RequestService.create("my_qq_test")
+                    .byAuthorizationCode("D8C3B5E8B55E4AAAC8EA1FB8DC0AFCEC")
+                    .request("me").get().as(Map.class);
+            System.out.println(meInfo);
+        } catch (OAuth2RequestException e) {
+            System.out.println(e.getErrorType() + ":" + e.getResponse().as(Map.class));
+        }
+    }
+
+    @Test
+    public void testCrud() throws Exception {
+        OAuth2ServerConfigEntity entity = entityFactory.newInstance(OAuth2ServerConfigEntity.class);
+        //todo 设置测试属性
+        entity.setName("test");
+
+        // test add data
+        String requestBody = JSON.toJSONString(entity);
+        JSONObject result = testPost("/oauth2-server-config").setUp(setup -> setup.contentType(MediaType.APPLICATION_JSON).content(requestBody)).exec().resultAsJson();
+        Assert.assertEquals(200, result.get("status"));
+        String id = result.getString("result");
+        Assert.assertNotNull(id);
+        entity.setId(id);
+        // test get data
+        result = testGet("/oauth2-server-config/" + id).exec().resultAsJson();
+        entity = result.getObject("result", entityFactory.getInstanceType(OAuth2ServerConfigEntity.class));
+
+        Assert.assertEquals(200, result.get("status"));
+        Assert.assertNotNull(result.getJSONObject("result"));
+
+        Assert.assertEquals(fastJsonHttpMessageConverter.converter(entity),
+                fastJsonHttpMessageConverter.converter(result.getObject("data", entityFactory.getInstanceType(OAuth2ServerConfigEntity.class))));
+        //todo 修改测试属性
+        OAuth2ServerConfigEntity newEntity = entityFactory.newInstance(OAuth2ServerConfigEntity.class);
+        newEntity.setName("test2");
+
+        result = testPut("/oauth2-server-config/" + id)
+                .setUp(setup ->
+                        setup.contentType(MediaType.APPLICATION_JSON)
+                                .content(JSON.toJSONString(newEntity)))
+                .exec().resultAsJson();
+        Assert.assertEquals(200, result.get("status"));
+
+        result = testGet("/oauth2-server-config/" + id).exec().resultAsJson();
+        result = result.getJSONObject("result");
+        Assert.assertNotNull(result);
+
+        result = testDelete("/oauth2-server-config/" + id).exec().resultAsJson();
+        Assert.assertEquals(200, result.get("status"));
+
+        result = testGet("/oauth2-server-config/" + id).exec().resultAsJson();
+        Assert.assertEquals(404, result.get("status"));
+    }
+}

+ 58 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/java/org/hswebframework/web/starter/oauth2/client/QQResponseConvertSupport.java

@@ -0,0 +1,58 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.starter.oauth2.client;
+
+import com.alibaba.fastjson.JSON;
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+import org.hswebframework.web.service.oauth2.client.simple.request.definition.ResponseConvertForProviderDefinition;
+import org.hswebframework.web.service.oauth2.client.simple.request.definition.ResponseConvertForServerIdDefinition;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Component
+public class QQResponseConvertSupport implements ResponseConvertForProviderDefinition {
+    @Override
+    public <T> T convert(OAuth2Response response, Class<T> type) {
+        String json = response.asString();
+        if (json.contains("callback(")) {
+            json = json.trim().substring("callback(".length(), json.length() - 3);
+        }
+        return JSON.parseObject(json, type);
+    }
+
+    @Override
+    public <T> List<T> convertList(OAuth2Response response, Class<T> type) {
+        String json = response.asString();
+        if (json.contains("callback(")) {
+            json = json.trim().substring("callback(".length(), json.length() - 3);
+        }
+        return JSON.parseArray(json, type);
+    }
+
+    @Override
+    public String getProvider() {
+        return "QQ";
+    }
+}

+ 87 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/java/org/hswebframework/web/starter/oauth2/client/QQResponseJudgeSupport.java

@@ -0,0 +1,87 @@
+/*
+ *  Copyright 2016 http://www.hswebframework.org
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *
+ */
+
+package org.hswebframework.web.starter.oauth2.client;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import org.hswebframework.web.authorization.oauth2.client.response.OAuth2Response;
+import org.hswebframework.web.service.oauth2.client.simple.request.definition.ResponseJudgeForProviderDefinition;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TODO 完成注释
+ *
+ * @author zhouhao
+ */
+@Component
+public class QQResponseJudgeSupport implements ResponseJudgeForProviderDefinition {
+    static Map<String, OAuth2Response.ErrorType> errorTypeMap = new HashMap<>();
+
+    static {
+        /*
+        http://wiki.connect.qq.com/%E5%85%AC%E5%85%B1%E8%BF%94%E5%9B%9E%E7%A0%81%E8%AF%B4%E6%98%8E
+         */
+        // success
+        errorTypeMap.put("0", null);
+
+        errorTypeMap.put("100000", OAuth2Response.ErrorType.ILLEGAL_RESPONSE_TYPE);
+        errorTypeMap.put("100001", OAuth2Response.ErrorType.ILLEGAL_CLIENT_ID);
+        // missing
+        errorTypeMap.put("100002", OAuth2Response.ErrorType.ILLEGAL_CLIENT_SECRET);
+        errorTypeMap.put("100003", OAuth2Response.ErrorType.ILLEGAL_AUTHORIZATION);
+        errorTypeMap.put("100004", OAuth2Response.ErrorType.ILLEGAL_GRANT_TYPE);
+        errorTypeMap.put("100005", OAuth2Response.ErrorType.ILLEGAL_CODE);
+        errorTypeMap.put("100006", OAuth2Response.ErrorType.ILLEGAL_REFRESH_TOKEN);
+        errorTypeMap.put("100007", OAuth2Response.ErrorType.ILLEGAL_ACCESS_TOKEN);
+        //param error
+        errorTypeMap.put("100009", OAuth2Response.ErrorType.ILLEGAL_CLIENT_SECRET);
+        errorTypeMap.put("100010", OAuth2Response.ErrorType.ILLEGAL_REDIRECT_URI);
+        errorTypeMap.put("100013", OAuth2Response.ErrorType.ILLEGAL_ACCESS_TOKEN);
+        errorTypeMap.put("100014", OAuth2Response.ErrorType.EXPIRED_TOKEN);
+        errorTypeMap.put("100015", OAuth2Response.ErrorType.INVALID_TOKEN);
+
+        errorTypeMap.put("100016", OAuth2Response.ErrorType.ILLEGAL_ACCESS_TOKEN);
+
+        errorTypeMap.put("100019", OAuth2Response.ErrorType.ILLEGAL_CODE);
+
+    }
+
+    @Override
+    public String getProvider() {
+        return "QQ";
+    }
+
+    @Override
+    public OAuth2Response.ErrorType judge(OAuth2Response response) {
+        String result = response.asString();
+        if (result == null) return OAuth2Response.ErrorType.OTHER;
+        if (result.contains("callback(")) {
+            result = result.substring("callback(".length(), result.length() - 3);
+        }
+        JSONObject jsonRes = JSON.parseObject(result);
+        String error = jsonRes.getString("error");
+        if (error != null) {
+            return errorTypeMap.get(error);
+        }
+        return null;
+    }
+}

+ 13 - 0
hsweb-system/hsweb-system-oauth2-client/hsweb-system-oauth2-client-starter/src/test/resources/application.yml

@@ -0,0 +1,13 @@
+spring:
+    aop:
+        auto: true
+    datasource:
+       url : jdbc:h2:mem:oauth2.client_test_mem
+       username : sa
+       password :
+       type: com.alibaba.druid.pool.DruidDataSource
+       driver-class-name : org.h2.Driver
+hsweb:
+    app:
+      name: OAuth2服务配置测试
+      version: 3.0.0

+ 4 - 0
hsweb-system/hsweb-system-oauth2-client/pom.xml

@@ -31,6 +31,10 @@
     <packaging>pom</packaging>
     <modules>
         <module>hsweb-system-oauth2-client-controller</module>
+        <module>hsweb-system-oauth2-client-dao</module>
+        <module>hsweb-system-oauth2-client-entity</module>
+        <module>hsweb-system-oauth2-client-service</module>
+        <module>hsweb-system-oauth2-client-starter</module>
     </modules>