Cloud Native应用交付

  • 首页
  • 关于本站
  • 个人介绍
  • Downloads
  • Repo
    • Github
    • Container
  • F5
    • F5 Python SDK
    • F5-container
    • F5-LBaaS
  • 社交
    • 联系我
    • 微信/微博
    • 公众号
    • 打赏赞助
行至水穷处 坐看云起时
Cloud Native Application Services: cnadn.net
  1. 首页
  2. F5技术
  3. 正文

NGINX与oAuth2/OIDC系列三

2020年05月11日 8693点热度 1人点赞 0条评论

前面两篇(1 ,2),我们讲述了NGINX在authorization code模式下的能力,可以简单总结为NGINX既可以作为第三方应用(client)的验证代理,也可以作为Resource server角色对token进行验证或使用。在implicit模式下,NGINX能做什么呢?首先来看implicit模式的工作机制(最近太惨了,前两篇文章的画图ppt给不小心删除了,还清空了垃圾箱。。一般不没什么习惯清空垃圾箱的。。。就不重新画了,google一张图吧。。。)

在这个图里,把user想象你为,把client想象为一个浏览器然后从一个地方加载了一段纯浏览器本地运行的代码(比如react,angularJS什么的这些的纯前端实现),不需要服务器侧介入。可以看出这个过程比authorization code最大的特点就是少了server侧利用authorization code去取token的过程,授权服务器直接直接将token发给了浏览器,所以这也叫frontchannel模式,客户端是真的可以看到token的。显然在整个验证过程中,NGINX是没有什么机会介入的。因此在这种模式下,NGINX主要作为Resource Server的代理,帮助去验证相关token,并将必要的token内的信息传递后后端的服务器。

所以只要客户端浏览器将token通过合适的方式送给NGINX就可以。

Token有两种格式,一种是常见的JWT,这是一种可以offline 验证的,而且其内容是可以被直接解开的,因此对这种JWT格式的token,只需要借助NGINX的 JWT模块就可以无需验证服务器endpoint参与(NGINX上配置公开的JWK即可);另一种格式是一种私有格式,也就是非透明格式(Opaque),这种格式的token需要有验证端点来参与,这个验证过程就是所谓的token introspection(RFC7662)

在本篇实验里将基于google的JWT token方式。

Demo

图片来自nginx.com

前面的implicit模式的oAuth过程是通过goole提供的一个JS API写的,并使用了cookie.js API将客户端浏览器收到的access token转化存储到cookie里,后续浏览器带着这个Cookie来访问资源服务器(被NGINX代理)

1.准备工作,在网站的目录下放置用于客户端运行的代码以及相关的cookie.js文件

1
2
3
4
5
6
7
[root@plus1 oidc]# ll
total 12
-rw-r--r-- 1 root root 1446 May  9 14:37 index.html
-rw-r--r-- 1 root root 4772 May  9 12:28 js.cookie.js
[root@plus1 oidc]# pwd
/usr/share/nginx/html/oidc
[root@plus1 oidc]# cat index.html

html文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<html>
<head>
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
    <title>NGINX OpenID Connect demo</title>
    <!--google的js API用于和授权服务器通信并获取返回的token-->
    <script src="https://apis.google.com/js/platform.js" async defer></script>
    <meta name="google-signin-scope" content="profile email">
    <!--这里配置你的client securit-->
    <meta name="google-signin-client_id"
          content="423878601740-s7dvt2ic*******kcmih1cq2l.apps.googleusercontent.com">
    <!--cookie js 用于实现将token写为cookie . 具体可以从这里获取https://github.com/js-cookie/js-cookie/blob/v2.1.2/src/js.cookie.js-->
    <script src="js.cookie.js"></script>
</head>
<body>
    <h2>NGINX OpenID Connect demo</h2>
    <hr/>
    <h3>Login with a Google account to get my <a href="/mysecurit/">MY SECURIT</a>.</h3>
    <table><tr><td>
    <div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div></td>
    <script>
      function onSignIn(googleUser) {
        var profile = googleUser.getBasicProfile();
        Cookies.set('auth_token', googleUser.getAuthResponse().id_token);
        document.getElementById('google_signout').innerHTML = '<a href="#" onclick="signOut();"><img src="' + profile.getImageUrl() + '" width=32 height=32>Sign out</a>';
      };
      function signOut() {
        var auth2 = gapi.auth2.getAuthInstance();
        auth2.signOut().then(function () {
          Cookies.remove('auth_token');
          document.getElementById('google_signout').innerHTML = '';
        });
      }
    </script>
    <td><div id="google_signout"></div></td>
    </tr></table>
    <hr/>
</body>
</html>

2.访问oidc.cnadn.net/mysecurit 请求抵达NGINX后,命中以下配置。配置使用JWT模块进行认证,客户端是通过将token放在auth_token这个Cookie传上来。这里要配置google公开的jwk文件来做验证,google JWK文件会定期轮换,所以这里需要自己额外配置cronjob定期去https://www.googleapis.com/oauth2/v3/certs 做更新。这是offline验证的缺点。 这里也可以将auth_jwt_key_file配置改为 auth_jwt_key_request https://www.googleapis.com/oauth2/v3/certs;采取线上认证。但由于环境里的NGINX机器并无不能爬梯子,所以只有用本地文件了

1
2
3
4
5
6
7
8
9
        location /mysecurit {
                auth_jwt "Google account" token=$cookie_auth_token;
                auth_jwt_key_file /etc/nginx/google_certs.jwk;
proxy_set_header x-jwt-email $jwt_claim_email;
                proxy_set_header x-jwt-name $jwt_claim_name;
                proxy_set_header x-jwt-locale $jwt_claim_locale;
                #root /usr/share/nginx/html;
                proxy_pass http://127.0.0.1:8080;
        }

3.由于首次访问不带cookie,因此jwt验证无法通过,将返回401错误,401错误将会被以下配置截获并处理。浏览器最终得到一个要求登录的提示。

1
2
3
4
5
          error_page 401 = @401;
          location @401 {
            default_type text/html;
            return 200 '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>OIDC loging redirect</title></head><body>You must <a href=/oidc/>LOGIN</a> first before pry securit!</boyd></html>';
          }

4. 用户点击登录提示里的LOGIN,页面会显示第一步中配置的html内容,由于用户尚未登录,因此google的API也无法取到用户的信息,因此提示客户最终登录GOOGLE(上述3,4两部存在两次引导登录过程,这里只是为了测试,实际可以将这个过程合并为一个)

5. 用户在Google的登录界面登录后,页面将自动获取到用户信息状态(google的API实现的),同时token被写入到cookie

6. 用户再次访问oidc.cnadn.net/mysecurit, 这次带了auth_token Cookie上来,因此JWT开始验证,如果通过则显示最终内容,即http://127.0.0.1:8080的内容:

1
2
3
4
5
6
7
    location /mysecurit {
    default_type text/html;
    set $email $http_x_jwt_email;
        set $name $auth_resp_x_vouch_idp_claims_blog$http_x_jwt_name;
        set $locale $http_x_jwt_locale;
    return 200 '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><h2>My securit is I know your:</h2><hr />Name: $name <br>email: $email <br>locale: $locale</html>';
}

过程记录

点击图片使用轮播模式

总结

利用NGINX plus的JWT模块实现在implicit模式下,作为资源服务器的replying part来对token进行验证。

对本文的最后一个系列,关于NGINX代理资源服务器进行token introspection验证模式,由于只是token验证形式的不同,对于oAuth整个流程来说都一样的,因此就不再重复阐述了,请直接参考:

oauth2-token-introspection-plus Plus可以将验证临时缓存在内存里,加速性能
oauth2-token-introspection-oss
Validating OAuth 2.0 Access Tokens with NGINX and NGINX Plus

相关文章

  • NGINX与oAuth2/OIDC系列二
  • NGINX与oAuth2/OIDC系列一
  • Better Alignment:多可用区双层负载下,如何借助F5避免局部NGINX后业务实例过载
  • How to build Nginx Plus as k8s Ingress controller and run with F5 CIS together
  • K8s nginx ingress controller 原理及测试
本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: nginx oAuth2 OIDC
最后更新:2020年05月22日

纳米

linjing.io

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理。

页面AI聊天助手
文章目录
  • Demo
  • 过程记录
  • 总结

纳米

linjing.io

☁️迈向Cloud Native ADC ☁️

认证获得:
TOGAF: ID 152743
Kubernetes: CKA #664
Microsoft: MCSE MCDBA
Cisco: CCNP
Juniper: JNCIS
F5:
F5 Certified Solution Expert, Security
F5 Certified Technology Specialist, LTM/GTM/APM/ASM
F5 Certified BIG-IP Administrator
  • 点击查看本博技术要素列表
  • 归档
    分类
    • AI
    • Automation
    • Avi Networks
    • Cisco ACI
    • CISCO资源
    • F5 with ELK
    • F5-Tech tips
    • F5技术
    • Juniper
    • Linux
    • NGINX
    • SDN
    • ServiceMesh
    • WEB编程
    • WINDOWS相关
    • 业界文章
    • 交换机技术
    • 化云为雨/Openstack
    • 协议原理
    • 容器/k8s
    • 我的工作
    • 我的生活
    • 网站技术
    • 路由器技术
    • 项目案例
    标签聚合
    openstack gtm istio flannel docker DNS F5 nginx bigip network neutron irule k8s api envoy
    最近评论
    汤姆 发布于 8 个月前(09月10日) 嗨,楼主,里面的json怎么下载啊,怎么收费啊?
    汤姆 发布于 8 个月前(09月09日) 大佬,kib的页面可以分享下吗?谢谢
    zhangsha 发布于 1 年前(05月12日) 资料发给我下,谢谢纳米同志!!!!lyx895@qq.com
    李成才 发布于 1 年前(01月02日) 麻烦了,谢谢大佬
    纳米 发布于 1 年前(01月02日) 你好。是的,因为以前下载系统插件在一次升级后将所有的下载生成信息全弄丢了。所以不少文件无法下载。DN...
    浏览次数
    • Downloads - 183,682 views
    • 联系我 - 118,966 views
    • 迄今为止最全最深入的BIGIP-DNS/GTM原理及培训资料 - 116,207 views
    • Github - 103,559 views
    • F5常见log日志解释 - 79,732 views
    • 从传统ADC迈向CLOUD NATIVE ADC - 下载 - 74,512 views
    • Sniffer Pro 4 70 530抓包软件 中文版+视频教程 - 74,320 views
    • 迄今为止最全最深入的BIGIP-DNS/GTM原理及培训资料 - 67,770 views
    • 关于本站 - 60,808 views
    • 这篇文档您是否感兴趣 - 55,463 views
    链接表
    • F5SE创新
    • Jimmy Song‘s Blog
    • SDNlab
    • Service Mesh社区
    • 三斗室
    • 个人profile
    • 云原生社区

    COPYRIGHT © 2023 Cloud Native 应用交付. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    京ICP备14048088号-1

    京公网安备 11010502041506号