行至水穷处 坐看“云”起时

Cloud Native ADN -> CNadn.Net

NGINX与oAuth2/OIDC系列二

在上篇中,通过将NGINX作为oAuth认证授权过程中的Client角色的代理,帮助应用直接实现oAuth认证登录。在这样一个过程中,我们采取的是authorization code的oAuth流程,取的是access_token,没有采用OIDC申请格式,并需要借助一个外部oauth proxy服务,那么是否可以完全依赖NGINX实现呢?

正如前篇文章所分析,在authorization code模式中需要 client 这个角色(就是代表第三方应用的,这里实际可以理解为NGINX)需要能够做以下几个事情:

  1. 收到未登录的用户请求或登录但ID token过期的请求,NGINX要向客户端返回一个302,这个302 location中是构造IdP的验证url
  2. 用户开始在IdP上登录, IdP返回一个302跳转,location是预先设置的NGINX上的一个回调接口,并附着authorization code,
  3. NGINX收到该请求,获取code,向IdP发起请求获取access_code以及id token
  4. NGINX收到IdP的返回后,提取id token,执行有效性验证,如果验证ok,存取到本地和内存KV中,kv中用此次request的的request_id作为key,将id token整个存储在对应的value里
  5. NGINX发起302跳转给客户端,这里set一个cookie=上面的request_id给客户端
  6. 客户端发起一个带着cookie=request_id请求到NGINX上,NGINX根据该cookie提取kv里的对应的value,也就是提取到了id token,利用jwt模块执行校验,校验成功则通过,并将id token里的claims作为header送给后端应用

可以看出这个过程需要 njs模块编写javascript来实现子请求操作,使用jwt auth模块执行token验证,还需要keyval模块存储相关toke内容,因此只有NGINX Plus可以实现

Demo

NGINX 配置:

具体接js文件访问这里https://github.com/nginxinc/nginx-openid-connect/blob/R20/openid_connect.js

验证结果

附: OKTA申请APP过程

1.访问https://developer.okta.com/ 申请开发者账号

2.激活账号登录成功后,在界面增加一个app,类型选择web

3.参考如下填写信息,更换为你的实际域名

《NGINX与oAuth2/OIDC系列二》

4. 自动配置发现接口地址是 https://dev-yourid.okta.com/oauth2/default/.well-known/oauth-authorization-server 这个地址可以看到相关endpoint信息

其它参考

https://developer.okta.com/code/dotnet/jwt-validation/
https://developer.okta.com/docs/reference/api/oidc/

默认配置下返回的id token,payload包含类似:

总结

在本篇中,我们采用了NGINX Plus直接实现OIDC的验证过程,利用njs的子请求特性和简便的编程能力快速的扩展,从而实现了NGINX直接作为client角色(第三方应用代理角色)在整个authorization code通信模型中的工作。通过JWT模块实现对获取的id token进行验证。使用keyval模块以及cache功能存储和加速ID token的处理。 那么如果在oAuth的 implicit模式下,NGINX能做什么呢? 请继续看本系列的第三篇

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据