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,起名字后确认 + +![Image description](https://images.gitee.com/uploads/images/2021/0930/134455_9d56be50_9655714.png "屏幕截图.png") + +- 进入API library + +![Image description](https://images.gitee.com/uploads/images/2021/0930/134203_93592ed4_9655714.png "屏幕截图.png") + +- 选择social里的google+ api ,点击进入并enable 启用API + +![Image description](https://images.gitee.com/uploads/images/2021/0930/134705_737a4f10_9655714.png "屏幕截图.png") + +- 在API菜单的credential里,建立openid connect类型的API endpoint + +![Image description](https://images.gitee.com/uploads/images/2021/0930/135049_943398e8_9655714.png "屏幕截图.png") + +- 这时候会分配clientid和client secret给用户,好好保存。并且填写好回传的URL + +![Image description](https://images.gitee.com/uploads/images/2021/0930/135309_81514ca9_9655714.png "屏幕截图.png") + +- 配置授权认证时候显示的提示面板 + +![Image description](https://images.gitee.com/uploads/images/2021/0930/135746_6219bf8f_9655714.png "屏幕截图.png") + + +## 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;