diff --git a/README.md b/README.md
index aa0934943260e1e247f3e0245aedc854bd2cdd91..3c7689fa2b09ac21e3ae7989574182c130998897 100644
--- a/README.md
+++ b/README.md
@@ -12,4 +12,5 @@
- [1. 重学 Java 设计模式:适配器模式(多样MQ消息抽取需要数据)](https://bugstack.cn/itstack-demo-design/2020/06/02/%E9%87%8D%E5%AD%A6-Java-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E9%80%82%E9%85%8D%E5%99%A8%E6%A8%A1%E5%BC%8F.html)
- [2. 重学 Java 设计模式:实战桥接模式(多支付渠道「微信、支付宝」与多支付模式「刷脸、指纹」场景)](https://bugstack.cn/itstack-demo-design/2020/06/04/%E9%87%8D%E5%AD%A6-Java-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E6%88%98%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F.html)
-- [3. 重学 Java 设计模式:实战组合模式(营销差异化人群发券,决策树引擎搭建场景)](https://bugstack.cn/itstack-demo-design/2020/06/08/%E9%87%8D%E5%AD%A6-Java-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E6%88%98%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F.html)
\ No newline at end of file
+- [3. 重学 Java 设计模式:实战组合模式(营销差异化人群发券,决策树引擎搭建场景)](https://bugstack.cn/itstack-demo-design/2020/06/08/%E9%87%8D%E5%AD%A6-Java-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E6%88%98%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F.html)
+- [4. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)](https://bugstack.cn/itstack-demo-design/2020/06/09/%E9%87%8D%E5%AD%A6-Java-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F-%E5%AE%9E%E6%88%98%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F.html)
\ No newline at end of file
diff --git a/itstack-demo-design-9-00/pom.xml b/itstack-demo-design-9-00/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6d5160bd177d487d602cddb3c911facc2a1c89be
--- /dev/null
+++ b/itstack-demo-design-9-00/pom.xml
@@ -0,0 +1,15 @@
+
+
+
+ itstack-demo-design
+ org.itstack
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ itstack-demo-design-9-00
+
+
+
\ No newline at end of file
diff --git a/itstack-demo-design-9-00/src/main/java/org/itstack/demo/design/HandlerInterceptor.java b/itstack-demo-design-9-00/src/main/java/org/itstack/demo/design/HandlerInterceptor.java
new file mode 100755
index 0000000000000000000000000000000000000000..20e688fe763ea5d9e772fff893e8641b554bc427
--- /dev/null
+++ b/itstack-demo-design-9-00/src/main/java/org/itstack/demo/design/HandlerInterceptor.java
@@ -0,0 +1,7 @@
+package org.itstack.demo.design;
+
+public interface HandlerInterceptor {
+
+ boolean preHandle(String request, String response, Object handler);
+
+}
diff --git a/itstack-demo-design-9-00/src/main/java/org/itstack/demo/design/SsoInterceptor.java b/itstack-demo-design-9-00/src/main/java/org/itstack/demo/design/SsoInterceptor.java
new file mode 100755
index 0000000000000000000000000000000000000000..c7eaa727204e01c603a823e44305636e889ceb4c
--- /dev/null
+++ b/itstack-demo-design-9-00/src/main/java/org/itstack/demo/design/SsoInterceptor.java
@@ -0,0 +1,12 @@
+package org.itstack.demo.design;
+
+public class SsoInterceptor implements HandlerInterceptor{
+
+ public boolean preHandle(String request, String response, Object handler) {
+ // 模拟获取cookie
+ String ticket = request.substring(1, 8);
+ // 模拟校验
+ return ticket.equals("success");
+ }
+
+}
diff --git a/itstack-demo-design-9-00/src/test/java/org/itstack/demo/design/test/ApiTest.java b/itstack-demo-design-9-00/src/test/java/org/itstack/demo/design/test/ApiTest.java
new file mode 100755
index 0000000000000000000000000000000000000000..55abd8094bbf30ca70dd8c1a3847697b9e913ec7
--- /dev/null
+++ b/itstack-demo-design-9-00/src/test/java/org/itstack/demo/design/test/ApiTest.java
@@ -0,0 +1,16 @@
+package org.itstack.demo.design.test;
+
+import org.itstack.demo.design.SsoInterceptor;
+import org.junit.Test;
+
+public class ApiTest {
+
+ @Test
+ public void test_sso() {
+ SsoInterceptor ssoInterceptor = new SsoInterceptor();
+ String request = "1successhuahua";
+ boolean success = ssoInterceptor.preHandle(request, "ewcdqwt40liuiu", "t");
+ System.out.println("登录校验:" + request +(success ? " 放行" : " 拦截"));
+ }
+
+}
diff --git a/itstack-demo-design-9-01/pom.xml b/itstack-demo-design-9-01/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f995e302500750ca8ebf71b7f4f697337fc6ff7c
--- /dev/null
+++ b/itstack-demo-design-9-01/pom.xml
@@ -0,0 +1,23 @@
+
+
+
+ itstack-demo-design
+ org.itstack
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ itstack-demo-design-9-01
+
+
+ org.itstack
+ itstack-demo-design-9-00
+ 1.0-SNAPSHOT
+ compile
+
+
+
+
+
\ No newline at end of file
diff --git a/itstack-demo-design-9-01/src/main/java/org/itstack/demo/design/LoginSsoDecorator.java b/itstack-demo-design-9-01/src/main/java/org/itstack/demo/design/LoginSsoDecorator.java
new file mode 100755
index 0000000000000000000000000000000000000000..b4a33438dc6b480a3eccfcd4e0fa6b7fbbbce804
--- /dev/null
+++ b/itstack-demo-design-9-01/src/main/java/org/itstack/demo/design/LoginSsoDecorator.java
@@ -0,0 +1,32 @@
+package org.itstack.demo.design;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class LoginSsoDecorator extends SsoInterceptor {
+
+ private static Map authMap = new ConcurrentHashMap();
+
+ static {
+ authMap.put("huahua", "queryUserInfo");
+ authMap.put("doudou", "queryUserInfo");
+ }
+
+ @Override
+ public boolean preHandle(String request, String response, Object handler) {
+
+ // 模拟获取cookie
+ String ticket = request.substring(1, 8);
+ // 模拟校验
+ boolean success = ticket.equals("success");
+
+ if (!success) return false;
+
+ String userId = request.substring(9);
+ String method = authMap.get(userId);
+
+ // 模拟方法校验
+ return "queryUserInfo".equals(method);
+ }
+
+}
diff --git a/itstack-demo-design-9-01/src/test/java/org/itstack/demo/design/test/ApiTest.java b/itstack-demo-design-9-01/src/test/java/org/itstack/demo/design/test/ApiTest.java
new file mode 100755
index 0000000000000000000000000000000000000000..c5d0745634d702df50551af23d584147e8e60192
--- /dev/null
+++ b/itstack-demo-design-9-01/src/test/java/org/itstack/demo/design/test/ApiTest.java
@@ -0,0 +1,16 @@
+package org.itstack.demo.design.test;
+
+import org.itstack.demo.design.LoginSsoDecorator;
+import org.junit.Test;
+
+public class ApiTest {
+
+ @Test
+ public void test_LoginSsoDecorator() {
+ LoginSsoDecorator ssoDecorator = new LoginSsoDecorator();
+ String request = "1successhuahua";
+ boolean success = ssoDecorator.preHandle(request, "ewcdqwt40liuiu", "t");
+ System.out.println("登录校验:" + request + (success ? " 放行" : " 拦截"));
+ }
+
+}
diff --git a/itstack-demo-design-9-02/pom.xml b/itstack-demo-design-9-02/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bd0cf4e4a306f78f8eff9d97c3bc77013dd07371
--- /dev/null
+++ b/itstack-demo-design-9-02/pom.xml
@@ -0,0 +1,23 @@
+
+
+
+ itstack-demo-design
+ org.itstack
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ itstack-demo-design-9-02
+
+
+ org.itstack
+ itstack-demo-design-9-00
+ 1.0-SNAPSHOT
+ compile
+
+
+
+
+
\ No newline at end of file
diff --git a/itstack-demo-design-9-02/src/main/java/org/itstack/demo/design/LoginSsoDecorator.java b/itstack-demo-design-9-02/src/main/java/org/itstack/demo/design/LoginSsoDecorator.java
new file mode 100755
index 0000000000000000000000000000000000000000..1aefa10cf941f124f50fc7b67cea6d251df0eccb
--- /dev/null
+++ b/itstack-demo-design-9-02/src/main/java/org/itstack/demo/design/LoginSsoDecorator.java
@@ -0,0 +1,34 @@
+package org.itstack.demo.design;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class LoginSsoDecorator extends SsoDecorator {
+
+ private Logger logger = LoggerFactory.getLogger(LoginSsoDecorator.class);
+
+ private static Map authMap = new ConcurrentHashMap();
+
+ static {
+ authMap.put("huahua", "queryUserInfo");
+ authMap.put("doudou", "queryUserInfo");
+ }
+
+ public LoginSsoDecorator(HandlerInterceptor handlerInterceptor) {
+ super(handlerInterceptor);
+ }
+
+ @Override
+ public boolean preHandle(String request, String response, Object handler) {
+ boolean success = super.preHandle(request, response, handler);
+ if (!success) return false;
+ String userId = request.substring(8);
+ String method = authMap.get(userId);
+ logger.info("模拟单点登录方法访问拦截校验:{} {}", userId, method);
+ // 模拟方法校验
+ return "queryUserInfo".equals(method);
+ }
+}
diff --git a/itstack-demo-design-9-02/src/main/java/org/itstack/demo/design/SsoDecorator.java b/itstack-demo-design-9-02/src/main/java/org/itstack/demo/design/SsoDecorator.java
new file mode 100755
index 0000000000000000000000000000000000000000..3563ad061865a49973ffd59452fc156333a11fd7
--- /dev/null
+++ b/itstack-demo-design-9-02/src/main/java/org/itstack/demo/design/SsoDecorator.java
@@ -0,0 +1,17 @@
+package org.itstack.demo.design;
+
+public abstract class SsoDecorator implements HandlerInterceptor {
+
+ private HandlerInterceptor handlerInterceptor;
+
+ private SsoDecorator(){}
+
+ public SsoDecorator(HandlerInterceptor handlerInterceptor) {
+ this.handlerInterceptor = handlerInterceptor;
+ }
+
+ public boolean preHandle(String request, String response, Object handler) {
+ return handlerInterceptor.preHandle(request, response, handler);
+ }
+
+}
diff --git a/itstack-demo-design-9-02/src/test/java/org/itstack/demo/design/test/ApiTest.java b/itstack-demo-design-9-02/src/test/java/org/itstack/demo/design/test/ApiTest.java
new file mode 100755
index 0000000000000000000000000000000000000000..5a1b56afb49fa9ccb479a33890b89b663a8a4828
--- /dev/null
+++ b/itstack-demo-design-9-02/src/test/java/org/itstack/demo/design/test/ApiTest.java
@@ -0,0 +1,17 @@
+package org.itstack.demo.design.test;
+
+import org.itstack.demo.design.LoginSsoDecorator;
+import org.itstack.demo.design.SsoInterceptor;
+import org.junit.Test;
+
+public class ApiTest {
+
+ @Test
+ public void test_LoginSsoDecorator() {
+ LoginSsoDecorator ssoDecorator = new LoginSsoDecorator(new SsoInterceptor());
+ String request = "1successhuahua";
+ boolean success = ssoDecorator.preHandle(request, "ewcdqwt40liuiu", "t");
+ System.out.println("登录校验:" + request + (success ? " 放行" : " 拦截"));
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 7bc93209fd1eb223aa88ef2e039212ceaa9dcbc4..18f3afc3dd133ae43eab0cc0eeb65eb9be82f992 100755
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,9 @@
itstack-demo-design-7-02
itstack-demo-design-8-01
itstack-demo-design-8-02
+ itstack-demo-design-9-00
+ itstack-demo-design-9-01
+ itstack-demo-design-9-02