From 1740cb6b6d3bf14d9dd64a943464566285c12c6f Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Sat, 21 Apr 2018 17:00:46 +0800
Subject: [PATCH 01/20] Update readme

---
 README.md | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md
index 416da02..434778f 100644
--- a/README.md
+++ b/README.md
@@ -19,20 +19,20 @@
 </ol>
 <hr/>
 
-<strong>Java Config版本请访问Branch: <a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/config/">config</a></strong>
+<strong>Spring-Boot版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/config/">config</a></strong>
 
-<strong>MongoDB版本请访问Branch: <a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/mongodb/">mongodb</a></strong>
+<strong>MongoDB版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/mongodb/">mongodb</a></strong>
 
 <strong>OAuth2下一代身份认证授权协议OIDC实现: <a href="https://git.oschina.net/mkk/MyOIDC">MyOIDC</a></strong>
 <hr/>
 <h3>
-   OAuth2客户端项目请访问 <a href="http://git.oschina.net/mkk/spring-oauth-client">spring-oauth-client</a>
+   OAuth2客户端项目请访问 <a href="https://gitee.com/mkk/spring-oauth-client">spring-oauth-client</a>
 </h3>
 <h3>
    在线测试访问地址 <a href="http://andaily.com/spring-oauth-server/">http://andaily.com/spring-oauth-server/</a>
 </h3>
 <h4>
-   Shiro与OLTU整合的OAuth2项目 <a href="http://git.oschina.net/mkk/oauth2-shiro">http://git.oschina.net/mkk/oauth2-shiro</a>
+   Shiro与OLTU整合的OAuth2项目 <a href="https://gitee.com/mkk/oauth2-shiro">https://gitee.com/mkk/oauth2-shiro</a>
    (相比spring-oauth-server, 该项目入门门槛相对较低, 代码更加透明, 理解更容易,可扩展性更强, 且模块化开发)
 </h4>
 <hr/>
@@ -44,7 +44,7 @@
 项目是Maven管理的, 需要本地安装maven(开发用的maven版本号为3.1.0), 还有MySql(开发用的mysql版本号为5.6)
 </li>
 <li>
-<a href="http://git.oschina.net/shengzhao/spring-oauth-server/repository/archive?ref=master">下载</a>(或clone)项目到本地
+<a href="https://gitee.com/shengzhao/spring-oauth-server/repository/archive?ref=master">下载</a>(或clone)项目到本地
 </li>
 <li>
 创建MySQL数据库(如数据库名oauth2), 并运行相应的SQL脚本(脚本文件位于others/database目录),
@@ -52,7 +52,7 @@
    运行脚本的顺序: initial_db.ddl -> oauth.ddl -> initial_data.ddl
 </li>
 <li>
-修改<a href="http://git.oschina.net/shengzhao/spring-oauth-server/blob/master/src/main/resources/spring-oauth-server.properties">spring-oauth-server.properties</a>(位于src/main/resources目录)中的数据库连接信息(包括username, password等)
+修改<a href="https://gitee.com/shengzhao/spring-oauth-server/blob/master/src/main/resources/spring-oauth-server.properties">spring-oauth-server.properties</a>(位于src/main/resources目录)中的数据库连接信息(包括username, password等)
 </li>
 <li>
 将本地项目导入到IDE(如Intellij IDEA)中,配置Tomcat(或类似的servlet运行服务器), 并启动Tomcat(默认端口为8080);
@@ -63,7 +63,7 @@
          将war放在Tomcat中并启动(注意: 这种方式需要将spring-oauth-server.properties加入到classpath中并正确配置数据库连接信息).
 </li>
 <li>
-参考<a href="http://git.oschina.net/shengzhao/spring-oauth-server/blob/master/others/oauth_test.txt">oauth_test.txt</a>(位于others目录)的内容并测试之(也可在浏览器中访问相应的地址,如: http://localhost:8080/spring-oauth-server).
+参考<a href="https://gitee.com/shengzhao/spring-oauth-server/blob/master/others/oauth_test.txt">oauth_test.txt</a>(位于others目录)的内容并测试之(也可在浏览器中访问相应的地址,如: http://localhost:8080/spring-oauth-server).
 </li>
 </ol>
 </p>
@@ -93,8 +93,8 @@
 </li>
 <li>
 <p>
- 如果在使用过程中遇到特殊的问题(如:如何将oauth_code存入数据库),请访问项目的 <a href="http://git.oschina.net/shengzhao/spring-oauth-server/wikis/pages">Wiki</a> 
- 与 <a href="http://git.oschina.net/shengzhao/spring-oauth-server/attach_files">附件</a>. 
+ 如果在使用过程中遇到特殊的问题(如:如何将oauth_code存入数据库),请访问项目的 <a href="https://gitee.com/shengzhao/spring-oauth-server/wikis/pages">Wiki</a> 
+ 与 <a href="https://gitee.com/shengzhao/spring-oauth-server/attach_files">附件</a>. 
  <br/>
  我会把大家反馈的问题解决办法添加在这里.
  <br/>
@@ -105,7 +105,7 @@
 
 <li>
 <p>
- 如果在使用项目的过程中发现任何的BUG或者更好的提议, 建议将其提交到项目的 <a href="http://git.oschina.net/shengzhao/spring-oauth-server/issues">Issues</a> 中, 
+ 如果在使用项目的过程中发现任何的BUG或者更好的提议, 建议将其提交到项目的 <a href="https://gitee.com/shengzhao/spring-oauth-server/issues">Issues</a> 中, 
  我会一直关注并不断改进项目. 
 </p>
 </li>
@@ -115,10 +115,10 @@
 <strong>功能扩展</strong>
 <ol>
     <li>
-        <code>oauth_code存入数据库的配置</code>,  请下载文件 <a href="http://git.oschina.net/shengzhao/spring-oauth-server/attach_files">oauth_code存入数据库的配置.jpg</a>
+        <code>oauth_code存入数据库的配置</code>,  请下载文件 <a href="https://gitee.com/shengzhao/spring-oauth-server/attach_files">oauth_code存入数据库的配置.jpg</a>
     </li>
     <li>
-        <code>改变token过期的时间的配置</code>, 请下载文件<a href="http://git.oschina.net/shengzhao/spring-oauth-server/attach_files">改变token过期的时间的配置.jpg</a>
+        <code>改变token过期的时间的配置</code>, 请下载文件<a href="https://gitee.com/shengzhao/spring-oauth-server/attach_files">改变token过期的时间的配置.jpg</a>
     </li>
     <li>
         <code>自定义 grant_type</code>, 默认情况支持的grant_type包括 [password,authorization_code,refresh_token,implicit], 若不需要其中的某些grant_type,
@@ -152,7 +152,7 @@
 <p>
 从 0.3版本开始将项目的所有计划的开发内容列出来, 方便大家跟进, 也欢迎你加入.
 <br/>
-项目的开发管理使用开源项目 <a href="http://git.oschina.net/mkk/andaily-developer">andaily-developer</a>.
+项目的开发管理使用开源项目 <a href="https://gitee.com/mkk/andaily-developer">andaily-developer</a>.
 </p>
 <ul>
        <li>
@@ -227,7 +227,7 @@
             <ol>
                 <li><p>#73 - Upgrade 'spring-security-oauth2' version to '2.0.6.RELEASE' (current: 1.0.5.RELEASE)      [CANCELED]</p></li>
                 <li><p><del>#74 - oauth mysql ddl add create_time,  default is now()  </del></p></li>
-                <li><p><del>#75 - Add user information API, for <a href="http://git.oschina.net/mkk/spring-oauth-client"><code>spring-oauth-client</code></a> project use
+                <li><p><del>#75 - Add user information API, for <a href="https://gitee.com/mkk/spring-oauth-client"><code>spring-oauth-client</code></a> project use
         <pre>
         URL: /unity/user_info
         Login: Yes (ROLE_UNITY)
@@ -266,21 +266,21 @@
 <p>
     <ol>
         <li><p><em>2013-11-19</em>     Initial project, start push code</p></li>
-        <li><p><em>2013-11-20</em>     发布<a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.1/">0.1</a>版本</p></li>
+        <li><p><em>2013-11-20</em>     发布<a href="https://gitee.com/shengzhao/spring-oauth-server/tree/0.1/">0.1</a>版本</p></li>
         <li><p><em>2015-05-06</em>        发布<a href="http://www.oschina.net/news/62176/spring-oauth-server-0-2">0.2</a>版本</p></li>
         <li><p><em>2015-05-27</em>      创建项目博客,访问地址 <a href="http://andaily.com/blog/?cat=19">http://andaily.com/blog/?cat=19</a></p></li>
-        <li><p><em>2015-06-07</em>        发布<a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.3/">0.3</a>版本</p></li>
+        <li><p><em>2015-06-07</em>        发布<a href="https://gitee.com/shengzhao/spring-oauth-server/tree/0.3/">0.3</a>版本</p></li>
         <li><p>
             <em>2015-06-16</em>       添加github访问: <a href="https://github.com/monkeyk/spring-oauth-server">https://github.com/monkeyk/spring-oauth-server</a>,
             以后的更新将同步github与gitosc.
         </p></li>
         <li><p><em>2015-11-09</em>        开始开发 0.4-beta 版本</p></li>
-        <li><p><em>2015-11-18</em>        发布 <a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.4-beta/">0.4-beta</a> 版本</p></li>
-        <li><p><em>2016-01-02</em>        发布 <a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.4/">0.4</a> 版本</p></li>
+        <li><p><em>2015-11-18</em>        发布 <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/0.4-beta/">0.4-beta</a> 版本</p></li>
+        <li><p><em>2016-01-02</em>        发布 <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/0.4/">0.4</a> 版本</p></li>
         <li><p><em>2016-02-19</em>        Add 0.5 version development planning</p></li>
-        <li><p><em>2016-04-03</em>        Add <a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/config/">config</a> branch</p></li>
-        <li><p><em>2016-04-14</em>        Add <a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/mongodb/">mongodb</a> branch</p></li>
-        <li><p><em>2016-06-02</em>        发布 <a href="http://git.oschina.net/shengzhao/spring-oauth-server/tree/0.5/">0.5</a> 版本</p></li>
+        <li><p><em>2016-04-03</em>        Add <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/config/">config</a> branch</p></li>
+        <li><p><em>2016-04-14</em>        Add <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/mongodb/">mongodb</a> branch</p></li>
+        <li><p><em>2016-06-02</em>        发布 <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/0.5/">0.5</a> 版本</p></li>
         <li><p><em>2016-07-06</em>        Add 0.6 version planning</p></li>
         <li><p><em>2016-10-13</em>        发布0.6版本</p></li>
     </ol>

From ae29d52feb53cf61a7b145cab03827ea2fcff2f4 Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Sat, 21 Apr 2018 17:03:50 +0800
Subject: [PATCH 02/20] Update readme

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 434778f..fc68899 100644
--- a/README.md
+++ b/README.md
@@ -283,6 +283,7 @@
         <li><p><em>2016-06-02</em>        发布 <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/0.5/">0.5</a> 版本</p></li>
         <li><p><em>2016-07-06</em>        Add 0.6 version planning</p></li>
         <li><p><em>2016-10-13</em>        发布0.6版本</p></li>
+        <li><p><em>2018-04-21</em>        发布2.0.0版本, spring-boot版本</p></li>
     </ol>
 </p>
 

From 7b1e049dd86c120d488dc1b33069c0b471b0d7d5 Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Sat, 21 Apr 2018 17:05:17 +0800
Subject: [PATCH 03/20] Add config link

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index fc68899..58993f9 100644
--- a/README.md
+++ b/README.md
@@ -283,7 +283,7 @@
         <li><p><em>2016-06-02</em>        发布 <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/0.5/">0.5</a> 版本</p></li>
         <li><p><em>2016-07-06</em>        Add 0.6 version planning</p></li>
         <li><p><em>2016-10-13</em>        发布0.6版本</p></li>
-        <li><p><em>2018-04-21</em>        发布2.0.0版本, spring-boot版本</p></li>
+        <li><p><em>2018-04-21</em>        发布2.0.0版本, <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/config/" target="_blank">spring-boot版本</a></p></li>
     </ol>
 </p>
 

From b4dedba35e2ca77aa57d199b5b95ce1fe680a824 Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Sat, 21 Apr 2018 17:09:40 +0800
Subject: [PATCH 04/20] Update readme

---
 README.md | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 58993f9..e7d5efb 100644
--- a/README.md
+++ b/README.md
@@ -157,9 +157,23 @@
 <ul>
        <li>
             <p>
-                Version: <strong>1.0</strong> [pending]
+                Version: <strong>2.0</strong> [pending]
                 <br/>
-                Date: 2017-03-30 / ---
+                Date: 2018-04-09 / 2018-04-21
+            </p>
+            <ol>
+                <li><p><del>更新UI,为了更易理解与使用,场景化</del></p></li>
+                <li><p>增加删除access_token API</p></li>
+                <li><p>增加删除 refresh_token API</p></li>
+                <li><p>---</p></li>
+            </ol>
+            <br/>
+       </li>
+       <li>
+            <p>
+                Version: <strong>1.0</strong> [finished]
+                <br/>
+                Date: 2017-03-30 / 2018-04-04
             </p>
             <ol>
                 <li><p><del>implicit测试时 取消掉 client secret</del></p></li>

From 4b795b68bb06b7b1cf3bba2c3b45eeed7b89eac7 Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Sat, 21 Apr 2018 17:13:06 +0800
Subject: [PATCH 05/20] Update readme

---
 README.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/README.md b/README.md
index e7d5efb..9195912 100644
--- a/README.md
+++ b/README.md
@@ -163,8 +163,7 @@
             </p>
             <ol>
                 <li><p><del>更新UI,为了更易理解与使用,场景化</del></p></li>
-                <li><p>增加删除access_token API</p></li>
-                <li><p>增加删除 refresh_token API</p></li>
+                <li><strong>使用 spring-boot 重构</strong></li>
                 <li><p>---</p></li>
             </ol>
             <br/>

From 6513e2f351f97b42422c60146da1d974bc1a9f00 Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Sat, 21 Apr 2018 17:13:35 +0800
Subject: [PATCH 06/20] Update readme

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 9195912..d5f9356 100644
--- a/README.md
+++ b/README.md
@@ -163,7 +163,7 @@
             </p>
             <ol>
                 <li><p><del>更新UI,为了更易理解与使用,场景化</del></p></li>
-                <li><strong>使用 spring-boot 重构</strong></li>
+                <li><strong><del>使用 spring-boot 重构</del></strong></li>
                 <li><p>---</p></li>
             </ol>
             <br/>

From cb89a4aa85314c21aaef0ea17b8afe7d79650752 Mon Sep 17 00:00:00 2001
From: monkeyk7 <monkeyk1987@gmail.com>
Date: Tue, 24 Apr 2018 20:01:23 +0800
Subject: [PATCH 07/20] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d5f9356..9b19441 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@
 </ol>
 <hr/>
 
-<strong>Spring-Boot版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/config/">config</a></strong>
+<h3>Spring-Boot版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/config/">config</a></h3>
 
 <strong>MongoDB版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/mongodb/">mongodb</a></strong>
 
@@ -373,6 +373,9 @@
     与项目相关的,与OAuth2相关的问题与回答,以及各类讨论请访问<br/>
     <a href="http://andaily.com/blog/?dwqa-question_category=oauth">http://andaily.com/blog/?dwqa-question_category=oauth</a>
 </p>
+<p>
+    GitHub项目地址: <a href="https://github.com/monkeyk/spring-oauth-server.git">https://github.com/monkeyk/spring-oauth-server.git</a>
+</p>
 
 
 <hr/>

From 33e4b93eaacf1fe11a59d8ad5e443db1c0ecdfc4 Mon Sep 17 00:00:00 2001
From: monkeyk7 <monkeyk1987@gmail.com>
Date: Tue, 24 Apr 2018 20:02:32 +0800
Subject: [PATCH 08/20] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 9b19441..95a06cc 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@
    在线测试访问地址 <a href="http://andaily.com/spring-oauth-server/">http://andaily.com/spring-oauth-server/</a>
 </h3>
 <h4>
-   Shiro与OLTU整合的OAuth2项目 <a href="https://gitee.com/mkk/oauth2-shiro">https://gitee.com/mkk/oauth2-shiro</a>
+   Shiro与OLTU整合的OAuth2项目 <a href="https://gitee.com/mkk/oauth2-shiro">https://gitee.com/mkk/oauth2-shiro</a><br/>
    (相比spring-oauth-server, 该项目入门门槛相对较低, 代码更加透明, 理解更容易,可扩展性更强, 且模块化开发)
 </h4>
 <hr/>

From d0d9b2d47da8765324cdf7219faeb8e629b277ae Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Fri, 11 May 2018 18:27:19 +0800
Subject: [PATCH 09/20] Update readme

---
 README.md | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 95a06cc..28867f2 100644
--- a/README.md
+++ b/README.md
@@ -157,14 +157,25 @@
 <ul>
        <li>
             <p>
-                Version: <strong>2.0</strong> [pending]
+                Version: <strong>2.0.1</strong> [pending]
+                <br/>
+                Date: 2018-05-01 / ---
+            </p>
+            <ol>
+                <li><p>增加 /oauth/check_token 可使用   #IJO9H</p></li>
+                <li><p>Fix issue   #IJO9R</p></li>
+            </ol>
+            <br/>
+       </li>       
+       <li>
+            <p>
+                Version: <strong>2.0.0</strong> [finished]
                 <br/>
                 Date: 2018-04-09 / 2018-04-21
             </p>
             <ol>
                 <li><p><del>更新UI,为了更易理解与使用,场景化</del></p></li>
                 <li><strong><del>使用 spring-boot 重构</del></strong></li>
-                <li><p>---</p></li>
             </ol>
             <br/>
        </li>

From b905f9bb331b74cca22a5ddd0e15264711f8124c Mon Sep 17 00:00:00 2001
From: monkeyk7 <zhao@idsmanager.com>
Date: Wed, 23 May 2018 22:16:47 +0800
Subject: [PATCH 10/20] =?UTF-8?q?Fix=20=20/oauth/rest=5Ftoken=20=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3=20client=5Fsecret=E5=AD=97=E6=AE=B5=E6=B2=A1=E6=9C=89?=
 =?UTF-8?q?=E6=A0=A1=E9=AA=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md                                     |  2 +-
 .../web/controller/OAuthRestController.java   | 27 ++++++++++++++-----
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 28867f2..7742203 100644
--- a/README.md
+++ b/README.md
@@ -163,7 +163,7 @@
             </p>
             <ol>
                 <li><p>增加 /oauth/check_token 可使用   #IJO9H</p></li>
-                <li><p>Fix issue   #IJO9R</p></li>
+                <li><p><del>Fix issue   #IJO9R  /oauth/rest_token 接口 client_secret字段没有校验</del></p></li>
             </ol>
             <br/>
        </li>       
diff --git a/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java b/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java
index 7c52f4a..e893c9b 100644
--- a/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java
+++ b/src/main/java/com/monkeyk/sos/web/controller/OAuthRestController.java
@@ -137,6 +137,16 @@ public class OAuthRestController implements InitializingBean, ApplicationContext
         String clientId = getClientId(parameters);
         ClientDetails authenticatedClient = clientDetailsService.loadClientByClientId(clientId);
 
+        //validate client_secret
+        String clientSecret = getClientSecret(parameters);
+        if (clientSecret == null || clientSecret.equals("")) {
+            throw new InvalidClientException("Bad client credentials");
+        } else {
+            if (!clientSecret.equals(authenticatedClient.getClientSecret())) {
+                throw new InvalidClientException("Bad client credentials");
+            }
+        }
+
         TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
 
         if (clientId != null && !"".equals(clientId)) {
@@ -149,9 +159,7 @@ public class OAuthRestController implements InitializingBean, ApplicationContext
             }
         }
 
-        if (authenticatedClient != null) {
-            oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
-        }
+        oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
 
         final String grantType = tokenRequest.getGrantType();
         if (!StringUtils.hasText(grantType)) {
@@ -227,7 +235,7 @@ public class OAuthRestController implements InitializingBean, ApplicationContext
      *
      * @param e Exception
      * @return ResponseEntity
-     * @throws Exception
+     * @throws Exception Exception
      * @see org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint#handleException(Exception)
      */
     @ExceptionHandler(InvalidTokenException.class)
@@ -238,18 +246,23 @@ public class OAuthRestController implements InitializingBean, ApplicationContext
 
 
     private boolean isRefreshTokenRequest(Map<String, String> parameters) {
-        return "refresh_token".equals(parameters.get("grant_type")) && parameters.get("refresh_token") != null;
+        return "refresh_token".equals(parameters.get(OAuth2Utils.GRANT_TYPE)) && parameters.get("refresh_token") != null;
     }
 
     private boolean isAuthCodeRequest(Map<String, String> parameters) {
-        return "authorization_code".equals(parameters.get("grant_type")) && parameters.get("code") != null;
+        return "authorization_code".equals(parameters.get(OAuth2Utils.GRANT_TYPE)) && parameters.get("code") != null;
     }
 
 
     protected String getClientId(Map<String, String> parameters) {
-        return parameters.get("client_id");
+        return parameters.get(OAuth2Utils.CLIENT_ID);
     }
 
+    protected String getClientSecret(Map<String, String> parameters) {
+        return parameters.get("client_secret");
+    }
+
+
     private AuthenticationManager getAuthenticationManager() {
         return this.authenticationManager;
     }

From d5be7482432769791fdbd14176dfdd28468fa1f6 Mon Sep 17 00:00:00 2001
From: monkeyk7 <monkeyk1987@gmail.com>
Date: Tue, 5 Jun 2018 20:47:44 +0800
Subject: [PATCH 11/20] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 7742203..0b98d1f 100644
--- a/README.md
+++ b/README.md
@@ -416,6 +416,7 @@
         <li><p>南京索特科技 -- 200元 (2016-12-16)</p></li>
         <li><p>周广文 -- 6.66元 (2017-02-17)</p></li>
         <li><p>境随心转 -- 20元 (2017-06-09)</p></li>
+        <li><p>Xyz(秦) -- 50元 (2018-06-05)</p></li>
     </ul>
 </div>
 

From c7a66532f41dee082dee26389dc3861565ff178b Mon Sep 17 00:00:00 2001
From: monkeyk7 <monkeyk1987@gmail.com>
Date: Mon, 10 Sep 2018 13:30:21 +0800
Subject: [PATCH 12/20] GPL 2.0

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 0b98d1f..fe4a269 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 <strong>Spring与OAuth2的整合</strong>
 
 项目用Maven管理, 字符编码: UTF-8
-
+<em>授权协议:<a href="https://gitee.com/shengzhao/spring-oauth-server/tree/master/LICENSE">GPL 2.0</a></em>
 
 使用的技术与版本号
 <ol>

From 8d4fbd43c8cc03af28c5fa3d530b191bfdfbc7a8 Mon Sep 17 00:00:00 2001
From: monkeyk7 <monkeyk1987@gmail.com>
Date: Mon, 10 Sep 2018 13:31:08 +0800
Subject: [PATCH 13/20] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index fe4a269..b17492d 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,8 @@
 <strong>Spring与OAuth2的整合</strong>
 
 项目用Maven管理, 字符编码: UTF-8
-<em>授权协议:<a href="https://gitee.com/shengzhao/spring-oauth-server/tree/master/LICENSE">GPL 2.0</a></em>
+
+<em>授权协议:<a href="https://gitee.com/shengzhao/spring-oauth-server/tree/master/LICENSE">GPL-2.0</a></em>
 
 使用的技术与版本号
 <ol>

From ca2f8cb654872255bd25be737e41ea91e2426413 Mon Sep 17 00:00:00 2001
From: sz_ids <zhao@idsmanager.com>
Date: Sun, 16 Sep 2018 23:20:09 +0800
Subject: [PATCH 14/20] Update readme

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index b17492d..8a1ec27 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,10 @@
 </ol>
 <hr/>
 
+<h4>技术视频</h4>
+<a href="http://list.youku.com/albumlist/show/id_51900110.html">http://list.youku.com/albumlist/show/id_51900110.html</a>
+<hr/>
+
 <h3>Spring-Boot版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/config/">config</a></h3>
 
 <strong>MongoDB版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/mongodb/">mongodb</a></strong>

From b5bd4e9a4fe9381b360dfea80aa922bd8d4cf25d Mon Sep 17 00:00:00 2001
From: sz_ids <zhao@idsmanager.com>
Date: Sun, 16 Sep 2018 23:23:08 +0800
Subject: [PATCH 15/20] Update readme

---
 README.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 8a1ec27..0149c18 100644
--- a/README.md
+++ b/README.md
@@ -18,10 +18,9 @@
  <li>MySQL (5.6.23)</li>
  <li>EhCache (2.0.4)</li>
 </ol>
-<hr/>
-
 <h4>技术视频</h4>
 <a href="http://list.youku.com/albumlist/show/id_51900110.html">http://list.youku.com/albumlist/show/id_51900110.html</a>
+
 <hr/>
 
 <h3>Spring-Boot版本请访问Branch: <a href="https://gitee.com/shengzhao/spring-oauth-server/tree/config/">config</a></h3>

From 541e64c0909e573f6f02dec7e4bf7e4cb387a22e Mon Sep 17 00:00:00 2001
From: sz_ids <zhao@idsmanager.com>
Date: Sun, 16 Sep 2018 23:23:44 +0800
Subject: [PATCH 16/20] Update readme

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 0149c18..cfcfd1b 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@
  <li>EhCache (2.0.4)</li>
 </ol>
 <h4>技术视频</h4>
-<a href="http://list.youku.com/albumlist/show/id_51900110.html">http://list.youku.com/albumlist/show/id_51900110.html</a>
+<a href="http://list.youku.com/albumlist/show/id_51900110.html" target="_blank">http://list.youku.com/albumlist/show/id_51900110.html</a>
 
 <hr/>
 

From baf524f115ce63fb261fcc8977c2c59e6dafdfaf Mon Sep 17 00:00:00 2001
From: monkeyk7 <monkeyk1987@gmail.com>
Date: Mon, 17 Sep 2018 12:24:44 +0800
Subject: [PATCH 17/20] =?UTF-8?q?(=E6=8C=81=E7=BB=AD=E6=9B=B4=E6=96=B0...)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index cfcfd1b..0b7c096 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,7 @@
 </ol>
 <h4>技术视频</h4>
 <a href="http://list.youku.com/albumlist/show/id_51900110.html" target="_blank">http://list.youku.com/albumlist/show/id_51900110.html</a>
+(持续更新...)
 
 <hr/>
 

From 0a6a322829c3ccef74580efb5cd0aba63e7008c7 Mon Sep 17 00:00:00 2001
From: sz_ids <zhao@idsmanager.com>
Date: Sun, 14 Oct 2018 22:00:30 +0800
Subject: [PATCH 18/20] Update readme

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 0b7c096..ea4f92a 100644
--- a/README.md
+++ b/README.md
@@ -169,6 +169,8 @@
             <ol>
                 <li><p>增加 /oauth/check_token 可使用   #IJO9H</p></li>
                 <li><p><del>Fix issue   #IJO9R  /oauth/rest_token 接口 client_secret字段没有校验</del></p></li>
+                <li><p><del>升级spring-boot 版本为 2.0.2.RELEASE</del></p></li>
+                <li><p><del>将项目用视频方式展现出来,更直观</del></p></li>
             </ol>
             <br/>
        </li>       

From 5cbf8454f67b9142d530ec9f78ef1f75a937b293 Mon Sep 17 00:00:00 2001
From: sz_ids <zhao@idsmanager.com>
Date: Sun, 14 Oct 2018 22:03:26 +0800
Subject: [PATCH 19/20] Update readme, task list

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index ea4f92a..d86ed90 100644
--- a/README.md
+++ b/README.md
@@ -170,7 +170,7 @@
                 <li><p>增加 /oauth/check_token 可使用   #IJO9H</p></li>
                 <li><p><del>Fix issue   #IJO9R  /oauth/rest_token 接口 client_secret字段没有校验</del></p></li>
                 <li><p><del>升级spring-boot 版本为 2.0.2.RELEASE</del></p></li>
-                <li><p><del>将项目用视频方式展现出来,更直观</del></p></li>
+                <li><p><del>将项目用视频方式展现出来,更直观.  <a href="http://list.youku.com/albumlist/show/id_51900110.html" target="_blank>视频链接</a></del></p></li>
             </ol>
             <br/>
        </li>       

From d04bd2036fe107ef9e1bf175c500925a7b6cc194 Mon Sep 17 00:00:00 2001
From: sz_ids <zhao@idsmanager.com>
Date: Sun, 14 Oct 2018 22:50:27 +0800
Subject: [PATCH 20/20] =?UTF-8?q?=E9=87=8D=E6=9E=84service=E4=BB=A3?=
 =?UTF-8?q?=E7=A0=81=EF=BC=8C=E6=B7=BB=E5=8A=A0business=E5=B1=82=EF=BC=9Bc?=
 =?UTF-8?q?ontext=20=E9=A1=B5=E9=9D=A2=E5=B1=95=E7=A4=BA=E5=B7=B2=E7=BB=8F?=
 =?UTF-8?q?=E7=99=BB=E5=BD=95=20=E7=9A=84=E7=94=A8=E6=88=B7=E5=90=8D=20?=
 =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7=E5=90=8E=E5=8A=A0=E5=85=A5?=
 =?UTF-8?q?=E7=BC=93=E5=AD=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../sos/infrastructure/CacheConstants.java    | 15 +++----
 .../sos/infrastructure/SOSCacheUtils.java     | 41 ++++++++++++++++++
 .../business/CurrentUserJsonDtoLoader.java    | 40 +++++++++++++++++
 .../business/OauthUserJsonDtoLoader.java      | 35 +++++++++++++++
 .../sos/service/business/UserFormSaver.java   | 43 +++++++++++++++++++
 .../sos/service/impl/UserServiceImpl.java     | 35 +++------------
 .../monkeyk/sos/web/context/BeanProvider.java | 39 +++++++++++++++++
 .../web/context/SOSContextLoaderListener.java | 28 ++++++++++++
 src/main/webapp/WEB-INF/web.xml               |  4 +-
 src/main/webapp/index.jsp                     | 20 ++++++---
 10 files changed, 255 insertions(+), 45 deletions(-)
 create mode 100644 src/main/java/com/monkeyk/sos/infrastructure/SOSCacheUtils.java
 create mode 100644 src/main/java/com/monkeyk/sos/service/business/CurrentUserJsonDtoLoader.java
 create mode 100644 src/main/java/com/monkeyk/sos/service/business/OauthUserJsonDtoLoader.java
 create mode 100644 src/main/java/com/monkeyk/sos/service/business/UserFormSaver.java
 create mode 100644 src/main/java/com/monkeyk/sos/web/context/BeanProvider.java
 create mode 100644 src/main/java/com/monkeyk/sos/web/context/SOSContextLoaderListener.java

diff --git a/src/main/java/com/monkeyk/sos/infrastructure/CacheConstants.java b/src/main/java/com/monkeyk/sos/infrastructure/CacheConstants.java
index 3fe0f37..59b0f89 100644
--- a/src/main/java/com/monkeyk/sos/infrastructure/CacheConstants.java
+++ b/src/main/java/com/monkeyk/sos/infrastructure/CacheConstants.java
@@ -9,35 +9,32 @@ package com.monkeyk.sos.infrastructure;
  *
  * @author Shengzhao Li
  */
-public abstract class CacheConstants {
+public interface CacheConstants {
 
     /**
      * client Details Cache, key is clientId
      */
-    public static final String CLIENT_DETAILS_CACHE = "clientDetailsCache";
+    String CLIENT_DETAILS_CACHE = "clientDetailsCache";
 
     /**
      * access Token Cache, key is token
      */
-    public static final String ACCESS_TOKEN_CACHE = "accessTokenCache";
+    String ACCESS_TOKEN_CACHE = "accessTokenCache";
 
     /**
      * refresh Token Cache, key is token
      */
-    public static final String REFRESH_TOKEN_CACHE = "refreshTokenCache";
+    String REFRESH_TOKEN_CACHE = "refreshTokenCache";
 
     /**
      * authorization Code Cache, key is code
      */
-    public static final String AUTHORIZATION_CODE_CACHE = "authorizationCodeCache";
+    String AUTHORIZATION_CODE_CACHE = "authorizationCodeCache";
 
     /**
      * user Cache, key is username
      */
-    public static final String USER_CACHE = "userCache";
+    String USER_CACHE = "userCache";
 
 
-    private CacheConstants() {
-    }
-
 }
diff --git a/src/main/java/com/monkeyk/sos/infrastructure/SOSCacheUtils.java b/src/main/java/com/monkeyk/sos/infrastructure/SOSCacheUtils.java
new file mode 100644
index 0000000..27073b1
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/infrastructure/SOSCacheUtils.java
@@ -0,0 +1,41 @@
+package com.monkeyk.sos.infrastructure;
+
+import com.monkeyk.sos.web.context.BeanProvider;
+import org.springframework.cache.Cache;
+import org.springframework.cache.CacheManager;
+import org.springframework.util.Assert;
+
+/**
+ * 2018/10/14
+ * <p>
+ * <p>
+ * Cache 操作相关
+ *
+ * @author Shengzhao Li
+ * @since 1.0
+ */
+public class SOSCacheUtils implements CacheConstants {
+
+
+    private SOSCacheUtils() {
+    }
+
+
+    /**
+     * 用户 Cache
+     *
+     * @return Cache instance
+     */
+    public static Cache userCache() {
+        final CacheManager cacheManager = getCacheManager();
+        return cacheManager.getCache(USER_CACHE);
+    }
+
+    private static CacheManager getCacheManager() {
+        final CacheManager cacheManager = BeanProvider.getBean(CacheManager.class);
+        Assert.notNull(cacheManager, "cacheManager is null");
+        return cacheManager;
+    }
+
+
+}
diff --git a/src/main/java/com/monkeyk/sos/service/business/CurrentUserJsonDtoLoader.java b/src/main/java/com/monkeyk/sos/service/business/CurrentUserJsonDtoLoader.java
new file mode 100644
index 0000000..d7c6706
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/business/CurrentUserJsonDtoLoader.java
@@ -0,0 +1,40 @@
+package com.monkeyk.sos.service.business;
+
+import com.monkeyk.sos.domain.dto.UserJsonDto;
+import com.monkeyk.sos.domain.shared.security.WdcyUserDetails;
+import com.monkeyk.sos.domain.user.UserRepository;
+import com.monkeyk.sos.web.context.BeanProvider;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+
+/**
+ * 2018/10/14
+ *
+ * @author Shengzhao Li
+ * @since 1.0
+ */
+public class CurrentUserJsonDtoLoader {
+
+
+    private transient UserRepository userRepository = BeanProvider.getBean(UserRepository.class);
+
+    public CurrentUserJsonDtoLoader() {
+    }
+
+    public UserJsonDto load() {
+
+        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        final Object principal = authentication.getPrincipal();
+
+        if (authentication instanceof OAuth2Authentication &&
+                (principal instanceof String || principal instanceof org.springframework.security.core.userdetails.User)) {
+            OauthUserJsonDtoLoader jsonDtoLoader = new OauthUserJsonDtoLoader((OAuth2Authentication) authentication);
+            return jsonDtoLoader.load();
+        } else {
+            final WdcyUserDetails userDetails = (WdcyUserDetails) principal;
+            return new UserJsonDto(userRepository.findByGuid(userDetails.user().guid()));
+        }
+    }
+
+}
diff --git a/src/main/java/com/monkeyk/sos/service/business/OauthUserJsonDtoLoader.java b/src/main/java/com/monkeyk/sos/service/business/OauthUserJsonDtoLoader.java
new file mode 100644
index 0000000..8acf119
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/business/OauthUserJsonDtoLoader.java
@@ -0,0 +1,35 @@
+package com.monkeyk.sos.service.business;
+
+import com.monkeyk.sos.domain.dto.UserJsonDto;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+
+import java.util.Collection;
+
+/**
+ * 2018/10/14
+ *
+ * @author Shengzhao Li
+ * @since 1.0
+ */
+public class OauthUserJsonDtoLoader {
+
+    private OAuth2Authentication oAuth2Authentication;
+
+    public OauthUserJsonDtoLoader(OAuth2Authentication oAuth2Authentication) {
+        this.oAuth2Authentication = oAuth2Authentication;
+    }
+
+    public UserJsonDto load() {
+
+        UserJsonDto userJsonDto = new UserJsonDto();
+        userJsonDto.setUsername(oAuth2Authentication.getName());
+
+        final Collection<GrantedAuthority> authorities = oAuth2Authentication.getAuthorities();
+        for (GrantedAuthority authority : authorities) {
+            userJsonDto.getPrivileges().add(authority.getAuthority());
+        }
+
+        return userJsonDto;
+    }
+}
diff --git a/src/main/java/com/monkeyk/sos/service/business/UserFormSaver.java b/src/main/java/com/monkeyk/sos/service/business/UserFormSaver.java
new file mode 100644
index 0000000..d185b02
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/service/business/UserFormSaver.java
@@ -0,0 +1,43 @@
+package com.monkeyk.sos.service.business;
+
+import com.monkeyk.sos.domain.dto.UserFormDto;
+import com.monkeyk.sos.domain.user.User;
+import com.monkeyk.sos.domain.user.UserRepository;
+import com.monkeyk.sos.infrastructure.SOSCacheUtils;
+import com.monkeyk.sos.web.WebUtils;
+import com.monkeyk.sos.web.context.BeanProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 2018/10/14
+ *
+ * @author Shengzhao Li
+ * @since 1.0
+ */
+public class UserFormSaver {
+
+
+    private static final Logger LOG = LoggerFactory.getLogger(UserFormSaver.class);
+
+    private transient UserRepository userRepository = BeanProvider.getBean(UserRepository.class);
+
+
+    private UserFormDto formDto;
+
+    public UserFormSaver(UserFormDto formDto) {
+        this.formDto = formDto;
+    }
+
+    public String save() {
+
+        User user = formDto.newUser();
+        userRepository.saveUser(user);
+        LOG.debug("{}|Save User: {}", WebUtils.getIp(), user);
+
+        //Add to cache
+        SOSCacheUtils.userCache().put(user.username(), user);
+
+        return user.guid();
+    }
+}
diff --git a/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java b/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java
index f7aabe6..78f0797 100644
--- a/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/monkeyk/sos/service/impl/UserServiceImpl.java
@@ -8,16 +8,13 @@ import com.monkeyk.sos.domain.shared.security.WdcyUserDetails;
 import com.monkeyk.sos.domain.user.User;
 import com.monkeyk.sos.domain.user.UserRepository;
 import com.monkeyk.sos.service.UserService;
+import com.monkeyk.sos.service.business.CurrentUserJsonDtoLoader;
+import com.monkeyk.sos.service.business.UserFormSaver;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.oauth2.provider.OAuth2Authentication;
 import org.springframework.stereotype.Service;
 
-import java.util.Collection;
 import java.util.List;
 
 /**
@@ -43,16 +40,8 @@ public class UserServiceImpl implements UserService {
 
     @Override
     public UserJsonDto loadCurrentUserJsonDto() {
-        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-        final Object principal = authentication.getPrincipal();
-
-        if (authentication instanceof OAuth2Authentication &&
-                (principal instanceof String || principal instanceof org.springframework.security.core.userdetails.User)) {
-            return loadOauthUserJsonDto((OAuth2Authentication) authentication);
-        } else {
-            final WdcyUserDetails userDetails = (WdcyUserDetails) principal;
-            return new UserJsonDto(userRepository.findByGuid(userDetails.user().guid()));
-        }
+        CurrentUserJsonDtoLoader dtoLoader = new CurrentUserJsonDtoLoader();
+        return dtoLoader.load();
     }
 
     @Override
@@ -70,21 +59,9 @@ public class UserServiceImpl implements UserService {
 
     @Override
     public String saveUser(UserFormDto formDto) {
-        User user = formDto.newUser();
-        userRepository.saveUser(user);
-        return user.guid();
+        UserFormSaver saver = new UserFormSaver(formDto);
+        return saver.save();
     }
 
 
-    private UserJsonDto loadOauthUserJsonDto(OAuth2Authentication oAuth2Authentication) {
-        UserJsonDto userJsonDto = new UserJsonDto();
-        userJsonDto.setUsername(oAuth2Authentication.getName());
-
-        final Collection<GrantedAuthority> authorities = oAuth2Authentication.getAuthorities();
-        for (GrantedAuthority authority : authorities) {
-            userJsonDto.getPrivileges().add(authority.getAuthority());
-        }
-
-        return userJsonDto;
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/monkeyk/sos/web/context/BeanProvider.java b/src/main/java/com/monkeyk/sos/web/context/BeanProvider.java
new file mode 100644
index 0000000..ae3d845
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/web/context/BeanProvider.java
@@ -0,0 +1,39 @@
+package com.monkeyk.sos.web.context;
+
+import org.springframework.context.ApplicationContext;
+
+/**
+ * 2018/10/14
+ * <p>
+ * Spring bean容器, 启动时初始化
+ *
+ * @author Shengzhao Li
+ * @see SOSContextLoaderListener
+ * @since 1.0
+ */
+public abstract class BeanProvider {
+
+    private static ApplicationContext springApplicationContext;
+
+
+    //private
+    private BeanProvider() {
+    }
+
+    static void initialize(ApplicationContext applicationContext) {
+        BeanProvider.springApplicationContext = applicationContext;
+    }
+
+    public static <T> T getBean(Class<T> clazz) {
+        return springApplicationContext == null ? null : springApplicationContext.getBean(clazz);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getBean(String beanId) {
+        if (springApplicationContext == null) {
+            return null;
+        }
+        return (T) springApplicationContext.getBean(beanId);
+    }
+
+}
diff --git a/src/main/java/com/monkeyk/sos/web/context/SOSContextLoaderListener.java b/src/main/java/com/monkeyk/sos/web/context/SOSContextLoaderListener.java
new file mode 100644
index 0000000..f612289
--- /dev/null
+++ b/src/main/java/com/monkeyk/sos/web/context/SOSContextLoaderListener.java
@@ -0,0 +1,28 @@
+package com.monkeyk.sos.web.context;
+
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+import javax.servlet.ServletContextEvent;
+
+/**
+ * 2018/10/14
+ * <p>
+ * <p>
+ * 扩展 Spring Context, 方便获取 bean
+ *
+ * @author Shengzhao Li
+ * @since 1.0
+ */
+public class SOSContextLoaderListener extends ContextLoaderListener {
+
+
+    @Override
+    public void contextInitialized(ServletContextEvent event) {
+        super.contextInitialized(event);
+        //ext
+        WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(event.getServletContext());
+        BeanProvider.initialize(applicationContext);
+    }
+}
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index 220efb5..81351d7 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -132,11 +132,11 @@
     </listener>
 
     <!--
-        Spring Context 监听
+        Spring Context 监听, 扩展实现l
     -->
     <!-- Spring context listener -->
     <listener>
-        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+        <listener-class>com.monkeyk.sos.web.context.SOSContextLoaderListener</listener-class>
     </listener>
 
 
diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp
index 41ba345..a2ddf86 100644
--- a/src/main/webapp/index.jsp
+++ b/src/main/webapp/index.jsp
@@ -5,6 +5,7 @@
 
 <%@ page contentType="text/html;charset=UTF-8" language="java" trimDirectiveWhitespaces="true" %>
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
 <!DOCTYPE HTML>
 <html>
 <head>
@@ -17,11 +18,20 @@
     <small class="badge" title="Version">1.0</small>
 </h2>
 
-<p>
-    <a href="${contextPath}/login.jsp">Login</a>
-    &nbsp;|&nbsp;
-    <a href="${contextPath}/logout.do">Logout</a>
-</p>
+<c:if test="${not empty SPRING_SECURITY_CONTEXT.authentication.principal.username}" var="logged">
+    Logged: <sec:authentication property="principal.username"/>
+    <p>
+        <a href="${contextPath}/logout.do">Logout</a>
+    </p>
+</c:if>
+<c:if test="${not logged}">
+    <p>
+        <a href="${contextPath}/login.jsp">Login</a>
+        &nbsp;|&nbsp;
+        <a href="${contextPath}/logout.do">Logout</a>
+    </p>
+</c:if>
+
 
 <div>
     操作说明: