diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/README.md" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/README.md"
new file mode 100644
index 0000000000000000000000000000000000000000..1eb3212fdb4cfb9801eaf90fd186b6cac6d14675
--- /dev/null
+++ "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/README.md"
@@ -0,0 +1,142 @@
+# Lab环境介绍
+
+本次演示的是利用Nginx Plus实现OAUTH2.0 Implicit Flow流程的认证授权。具体细节:
+
+
+
+- Nginx Plus自身有一个存放静态页面的目录,同时也作为后端资源的一个反代。
+- 用户通过Nginx Plus上的一个静态主页,可以访问以上的两个资源。
+- 如果访问这两个资源,都需要通过GCP的OIDC的认证,获取到access token。 NGINX PLUS验证access token后,放行对资源的访问。
+
+
+## NGINX Plus配置说明
+
+nginx部分配置:
+```nginx
+server {
+
+ listen 88;
+ root /var/www/public_html;
+
+ location /private/ {
+ auth_jwt "Google account" token=$cookie_auth_token;
+ auth_jwt_key_file /etc/nginx/google_certs.jwk;
+ }
+
+ location /f5demo/ {
+ auth_jwt "Google account" token=$cookie_auth_token;
+ auth_jwt_key_file /etc/nginx/google_certs.jwk;
+ proxy_pass http://api_server/;
+ }
+
+ }
+```
+1. 监听端口 88;按需修改
+2. 主页资源目录放在 `/var/www/`中
+3. `/private/`资源是静态页面,资源存放在`/var/www`下。`/f5demo/`资源是做了反代,转发到后台api server资源。
+4. 去以上资源都需要通过jwt token的效验。 其中用于验证jwt token的key文件存放在`/etc/nginx/`下。
+5. nginx plus收到请求会通过`token=$cookie_auth_token;`定义的变量,从http头部的cookie获取`name=auth_token`的cookie值
+
+6. 获取google token验证用的key:
+ ```
+ 0 * * * * wget https://www.googleapis.com/oauth2/v3/certs -O /etc/nginx/google_certs.jwk
+ ```
+ google key会定期更新,可以如上写一个crontab来定期更新获取jwt key。
+
+
+## HTML登录主页说明
+对在`/var/www/public_html/index.html`内容进行说明:
+```html
+
+
+
+
+ Anxin Training NGINX OpenID Connect Demo by ColinJi
+
+
+
+
+
+
+ Anxin Training NGINX OpenID Connect Demo by ColinJi
+
+ Login with a Google account then visit the private area.
+ Login with a Google account then proxy to f5demo.
+
+
+
+
+```
+
+核心部分说明:
+```html
+
+
+
+```
+- `google-signin-client_id` tag : 使用google的oauth2.0 JS API,这里需要提供注册后获取的clientid
+- `js.cookie.js` : 轻量的js用于解析access token,并在请求中作为cookie的值。在后面使用的`cookie.set` 就是利用了这个库
+
+
+---
+
+# 实验步骤
+
+## Google GCP上注册应用
+
+
+- 建立一个新的project,起名字后确认
+
+
+
+- 进入API library
+
+
+
+- 选择social里的google+ api ,点击进入并enable 启用API
+
+
+
+- 在API菜单的credential里,建立openid connect类型的API endpoint
+
+
+
+- 这时候会分配clientid和client secret给用户,好好保存。并且填写好回传的URL
+
+
+
+- 配置授权认证时候显示的提示面板
+
+
+
+
+## NGINX PLUS 配置
+
+1. 应用lab里的配置文件和相关资源,注意路径一致。
+2. 注意使用最新的google jwt key:
+ ```
+ wget https://www.googleapis.com/oauth2/v3/certs -O /etc/nginx/google_certs.jwk
+ ```
+3. nginx plus上有两个资源, /f5demo/需要自己额外再搭一个普通web服务器即可。 /private/的资源已经上传,是一个静态图片.
+
+## 客户端注意事项
+1. 注意因为google无法访问,需要额外处理。
\ No newline at end of file
diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/nginx.conf" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/nginx.conf"
new file mode 100644
index 0000000000000000000000000000000000000000..1f5ba19409d4623b6fc14a96aef70d7fec000665
--- /dev/null
+++ "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/nginx.conf"
@@ -0,0 +1,58 @@
+
+user nginx;
+worker_processes auto;
+
+error_log /var/log/nginx/error.log notice;
+pid /var/run/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ '$status $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for"';
+
+ access_log /var/log/nginx/access.log main;
+
+ sendfile on;
+
+
+ keepalive_timeout 65;
+
+ #自己后台搭建个web资源即可
+ upstream api_server {
+ server 10.1.20.11;
+ server 10.1.20.12;
+ }
+
+
+
+ server {
+
+ listen 88;
+ root /var/www/public_html;
+
+ location /private/ {
+ auth_jwt "Google account" token=$cookie_auth_token;
+ auth_jwt_key_file /etc/nginx/google_certs.jwk;
+ }
+
+ location /f5demo/ {
+ auth_jwt "Google account" token=$cookie_auth_token;
+ auth_jwt_key_file /etc/nginx/google_certs.jwk;
+ proxy_pass http://api_server/;
+ }
+
+ }
+
+
+}
+
+
diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/index.html" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/index.html"
new file mode 100644
index 0000000000000000000000000000000000000000..f241270c6c111cd65f0dffd3367352c0357ef56d
--- /dev/null
+++ "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/index.html"
@@ -0,0 +1,37 @@
+
+
+
+
+ Anxin Training NGINX OpenID Connect Demo by ColinJi
+
+
+
+
+
+
+ Anxin Training NGINX OpenID Connect Demo by ColinJi
+
+ Login with a Google account then visit the private area.
+ Login with a Google account then proxy to f5demo.
+
+
+
+
diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/js.cookie.js" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/js.cookie.js"
new file mode 100644
index 0000000000000000000000000000000000000000..7f3dffde69f8da3e870a198dfd4ccf04bc1e453c
--- /dev/null
+++ "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/js.cookie.js"
@@ -0,0 +1,151 @@
+/*!
+ * JavaScript Cookie v2.1.2
+ * https://github.com/js-cookie/js-cookie
+ *
+ * Copyright 2006, 2015 Klaus Hartl & Fagner Brack
+ * Released under the MIT license
+ */
+;(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(factory);
+ } else if (typeof exports === 'object') {
+ module.exports = factory();
+ } else {
+ var OldCookies = window.Cookies;
+ var api = window.Cookies = factory();
+ api.noConflict = function () {
+ window.Cookies = OldCookies;
+ return api;
+ };
+ }
+}(function () {
+ function extend () {
+ var i = 0;
+ var result = {};
+ for (; i < arguments.length; i++) {
+ var attributes = arguments[ i ];
+ for (var key in attributes) {
+ result[key] = attributes[key];
+ }
+ }
+ return result;
+ }
+
+ function init (converter) {
+ function api (key, value, attributes) {
+ var result;
+ if (typeof document === 'undefined') {
+ return;
+ }
+
+ // Write
+
+ if (arguments.length > 1) {
+ attributes = extend({
+ path: '/'
+ }, api.defaults, attributes);
+
+ if (typeof attributes.expires === 'number') {
+ var expires = new Date();
+ expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
+ attributes.expires = expires;
+ }
+
+ try {
+ result = JSON.stringify(value);
+ if (/^[\{\[]/.test(result)) {
+ value = result;
+ }
+ } catch (e) {}
+
+ if (!converter.write) {
+ value = encodeURIComponent(String(value))
+ .replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
+ } else {
+ value = converter.write(value, key);
+ }
+
+ key = encodeURIComponent(String(key));
+ key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
+ key = key.replace(/[\(\)]/g, escape);
+
+ return (document.cookie = [
+ key, '=', value,
+ attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE
+ attributes.path && '; path=' + attributes.path,
+ attributes.domain && '; domain=' + attributes.domain,
+ attributes.secure ? '; secure' : ''
+ ].join(''));
+ }
+
+ // Read
+
+ if (!key) {
+ result = {};
+ }
+
+ // To prevent the for loop in the first place assign an empty array
+ // in case there are no cookies at all. Also prevents odd result when
+ // calling "get()"
+ var cookies = document.cookie ? document.cookie.split('; ') : [];
+ var rdecode = /(%[0-9A-Z]{2})+/g;
+ var i = 0;
+
+ for (; i < cookies.length; i++) {
+ var parts = cookies[i].split('=');
+ var cookie = parts.slice(1).join('=');
+
+ if (cookie.charAt(0) === '"') {
+ cookie = cookie.slice(1, -1);
+ }
+
+ try {
+ var name = parts[0].replace(rdecode, decodeURIComponent);
+ cookie = converter.read ?
+ converter.read(cookie, name) : converter(cookie, name) ||
+ cookie.replace(rdecode, decodeURIComponent);
+
+ if (this.json) {
+ try {
+ cookie = JSON.parse(cookie);
+ } catch (e) {}
+ }
+
+ if (key === name) {
+ result = cookie;
+ break;
+ }
+
+ if (!key) {
+ result[name] = cookie;
+ }
+ } catch (e) {}
+ }
+
+ return result;
+ }
+
+ api.set = api;
+ api.get = function (key) {
+ return api(key);
+ };
+ api.getJSON = function () {
+ return api.apply({
+ json: true
+ }, [].slice.call(arguments));
+ };
+ api.defaults = {};
+
+ api.remove = function (key, attributes) {
+ api(key, '', extend(attributes, {
+ expires: -1
+ }));
+ };
+
+ api.withConverter = init;
+
+ return api;
+ }
+
+ return init(function () {});
+}));
diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/private/index.html" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/private/index.html"
new file mode 100644
index 0000000000000000000000000000000000000000..86fc6a74f5797940c5fd73e4d43fc59ba9775628
--- /dev/null
+++ "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/private/index.html"
@@ -0,0 +1,13 @@
+
+
+
+It is a Private of F5 SE Colin
+
+
+
+Private of F5 SE Colin
+hello world!
+
+
+
+
diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/private/npic.png" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/private/npic.png"
new file mode 100644
index 0000000000000000000000000000000000000000..a416ee02b97b784a40b4a5171c75baa4a18374dc
Binary files /dev/null and "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab1_implicit_flow_gcp/www/public_html/private/npic.png" differ
diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab2_author_code_flow_okta/README.md" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab2_author_code_flow_okta/README.md"
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git "a/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab3_token_introspection_okta/README.md" "b/10 NGINX\350\256\244\350\257\201\346\216\210\346\235\203/lab3_token_introspection_okta/README.md"
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git "a/5 NGINX\346\225\217\346\215\267\351\205\215\347\275\256/Web1/conf.d/default.conf" "b/5 NGINX\346\225\217\346\215\267\351\205\215\347\275\256/Web1/conf.d/default.conf"
index 0bf632510cecb81dcf34983fbe4b8b7392ff8939..707dccfd7dc162bb31ac81c9ec7dc4cbffb85f7d 100644
--- "a/5 NGINX\346\225\217\346\215\267\351\205\215\347\275\256/Web1/conf.d/default.conf"
+++ "b/5 NGINX\346\225\217\346\215\267\351\205\215\347\275\256/Web1/conf.d/default.conf"
@@ -9,7 +9,7 @@ server {
default_type application/json;
return 200 '{"deadlocks":{"healthy":true},"Disk":{"healthy":true},"Memory":{"healthy":true}}';
}
-
+
location / {
#root /usr/share/nginx/html;
#index index.html index.htm;