基于OIDC(OpenID Connect)的SSO(纯JS客户端)
来源:互联网 发布:西瓜影音for mac 编辑:程序博客网 时间:2024/05/17 08:58
在上一篇基于OIDC的SSO的中涉及到了4个Web站点:
oidc-server.dev:利用oidc实现的统一认证和授权中心,SSO站点。
oidc-client-hybrid.dev:oidc的一个客户端,采用hybrid模式。
oidc-client-implicit.dev:odic的另一个客户端,采用implicit模式。
oidc-client-js.dev:oidc的又一个客户端,采用implicit模式,纯静态网站,只有js和html,无服务端代码。
其中hybrid和implicit这两个站点都是具有在服务端执行代码的能力的(1,登录需要在服务端做跳转;2,登录状态写入cookie;3,通过服务端的接口接收被动的退出通知)。而js这个客户端则是一个纯粹的静态网站,那么它是如何处理登录和退出的呢?
oidc-client-js.dev这个web站点对应的代码位于web.oidc.client.js这个文件夹中(https://github.com/linianhui/oidc.example/tree/master/src/web.oidc.client.js):
JS Client 登录
我们知道在浏览器中的JS是可以直接进行页面跳转的,oidc的js客户端就是利用这个来直接构造认证请求的URL,然后进行登录跳转的(我们这里使用的是oidc-client.js这个开源的js库来处理oidc规范相关的一下操作的)。下图是打开oidc-client-js.dev后的页面:
JS Client 直接发起认证请求
我们点击下Login。
可以看到Client这边在对oidc-server.dev这个站点发起了2个请求之后就直接构造了一个认证请求的URL,并交给浏览器去发起了请求。
/account/js:我自己扩展的,后面介绍其用途,目前暂时忽略它。
/.well-known/openid-configuration:这个是之前介绍到的OIDC提供的Discovery服务,Client需要从这个服务返回的JSON中获取认证请求的接口地址以及其他的信息。
认证请求这里面包含的参数和上篇中的信息并没有什么差别,这里就不介绍了。
OIDC-Server 通过URL的#把数据传递给JS Client
浏览器会重定向到登录页面,我们登录一下,登录成功后会跳转上面所填写的redriect_uri参数指定的URL,并使用URL的#部分携带认证后的信息:
http://oidc-client-js.dev/oidc/login-callback.html#id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6ImI2MmE2YTVlZjNiNGJmOTlhNWU3M2FkZmI1OTQ3NjRjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MTE3NTEyMjgsImV4cCI6MTUxMTc1MTUyOCwiaXNzIjoiaHR0cDovL29pZGMtc2VydmVyLmRldiIsImF1ZCI6ImpzLWNsaWVudCIsIm5vbmNlIjoiZGU5NGI1NGMzNDk1NGFjMjg0Y2I0NzlhY2M5ZGMxMjMiLCJpYXQiOjE1MTE3NTEyMjgsImF0X2hhc2giOiJ1QnJhckVLOHk4elhwR0pJOG1BaE1nIiwic2lkIjoiMWQ2ZWQwYWI0ZjdhNzI2MDUxMzBiYjBkYjNiOTdkY2MiLCJzdWIiOiIwMDAwMDEiLCJhdXRoX3RpbWUiOjE1MTE3NTEyMjgsImlkcCI6ImxvY2FsIiwiYW1yIjpbImV4dGVybmFsIl19.EUMT0R34OKDuE8AESEnRAASoRCP2NCAy7EEkMdM9vBwfz8BGnrCGXiDnKoUgbw3qK8ekoiwhSed6qE-Xh5QqnnwQTOc_D0nucbA3CVqKDhc9TFonEHoU60ETbX0i70bbOThZeoJdto9CkILbcewk2SLgfCQXZzsKERm6AS7m9LUN7cGjQJQm6Ht5DpIgjFu7s9V7qnUfu7hjvI51zPmYgJwLtvCXb9vAxXy17oBrVTmYunDLETRnfj9UXcsSROOW6Ac6sKSLOtFkY5ElZuIa5Za_1GJFDaoYyZwFT53WWBO9-LBdIHd8Cqx5fyw8tlpT3qmdwf0scSr256sVXykGQw&access_token=eyJhbGciOiJSUzI1NiIsImtpZCI6ImI2MmE2YTVlZjNiNGJmOTlhNWU3M2FkZmI1OTQ3NjRjIiwidHlwIjoiSldUIn0.eyJuYmYiOjE1MTE3NTEyMjgsImV4cCI6MTUxMTc1NDgyOCwiaXNzIjoiaHR0cDovL29pZGMtc2VydmVyLmRldiIsImF1ZCI6WyJodHRwOi8vb2lkYy1zZXJ2ZXIuZGV2L3Jlc291cmNlcyIsIm15LWFwaSJdLCJjbGllbnRfaWQiOiJqcy1jbGllbnQiLCJzdWIiOiIwMDAwMDEiLCJhdXRoX3RpbWUiOjE1MTE3NTEyMjgsImlkcCI6ImxvY2FsIiwic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSIsIm15LWFwaSJdLCJhbXIiOlsiZXh0ZXJuYWwiXX0.BU65olTuhLSlyFHyRzSHKUaFw5v5qMg7qmutl3LCel0gtjD9ky9cyD3rUNNAkalVcHXg7znN_F2JB71ape9mSD_L66H8pTTwaiMTxbPz9_HMEz9w6GgmOrjMGP8unIpCOKom1DV4EiSQoDe8P30oh2mwmA5SLvZixlAln3_ycArTd7440SCUrUvnEa1CJyl-K-kkLvLyl3TRo6bDE-H47-AzHq1NtA22cwleVXNxUtOsMHk1Nsa2tOFW6B4t3fAvo_MWx2BFkJMBToy4ArepLXSaN5CQQxH8na1Havll3Ly3c9GOslNsm1krMvx9GYdFR6DgjoDvNbaVDkLdmO2T_w&token_type=Bearer&expires_in=3600&scope=openid%20profile%20my-api&state=96af404863044d49b6e14a5827862538&session_state=C33U-BpeYNeLhWhUuKLfup18cjKkKX54yCdL2fUOtV0.5ec877a6108fde6ad04e774a770d7ee1
这里相比上一篇中返回的信息多了一个access_token是因为我们的认证请求的response_type设置为了“id_token token”,故而oidc-server.dev把id_token和access_token一并给到了客户端。
JS Client 解析#中的数据,保存自己的登录状态
解析#后面的数据也是通过oidc-client.js 这个开源的库来实现的。解析后的数据呈现在页面上是如下这个样子。
其中登录后用户的信息保存在浏览器的SessionStorage中:
JS Client 主动登出
退出操作和其他类型的客户端一致,也是先清理自己保存的Session Storage,然后通知oidc-server.dev进行登出,这里就不详细解释了。
JS Client 被动登出
我们知道在SSO中,除了自身主动退出登录之外,还有其他的Client退出的时候,这里的JS Client也要被动的登出。由于JS Client没有服务端在服务端执行代码的能力,其登录状态也是保存在客户端这边的,那么它就没办法接收像其他的客户端一样接收到登出的通知了。这个时候就需要客户端自己主动去oidc-server.dev检查登录状态了。这一部分在OIDC中也有标准规范,体现在OIDC的Discovery服务中的check_session_iframe字段中。
这个地址checksession的地址是oidc-server.dev的地址,那么这个地址返回的html页面中,就可以通过js来检查去存储在cookie中的session信息的是否发生变化。然后通过H5中新增的postMessage来把这种变化传递给js client这边。js client再去检查一下是否已经登出了。如果已经登出,则会清理自身的登录状态来完成被动的登出操作。
比如下图。我再oidc-client-implicit.dev点击登出的时候,会触发oidc-server.dev清理自己的cookie,然后js-client中使用check_session_iframe这个隐藏的iframe可以检测到这种变化,从而使得js-client可以得知用户已经再其他的client退出登录。
自动登录
前面提到JS Client会加载一个oidc-server.dev/account/js的JS脚本文件,这个是我自己扩展出来的一个脚本。它会在这个纯静态的网站在一开使打开的时候告诉客户端oidc-server.dev是否已经登录了。
然后静态的网站就可以利用account这个变量来决定是否再打开网站的时候就自动去登录(由于其他站点已经登陆过了,那么oidc-server.dev站点会自动携带登录后的信息的再次跳转回来)。
读者可以打开浏览器,先打开oidc-client-implicit.dev这个站点并且登录,然后再打开oidc-client-js.dev这个站点的时候,就会发现它会自动的登录成功了。
总结
本篇介绍了再浏览器中运行的纯静态的HTML网站使如何使用OIDC服务进行单点登录,统一登出,登录状态监控,以及附加的如何让JS Client自动登录的原理。这里所使用的例子使传统的HTML+JS的结构。如果你使采用的Vue,Angular或者React的这类前端框架的话,那么其本质上的原理也是完全一样的,因为不管使采用的什么框架,最终输出给浏览器的还是HTML+JS而已。
参考
本文源代码:https://github.com/linianhui/oidc.example
oidc-client.js:https://github.com/IdentityModel/oidc-client-js
相关文章:
基于OIDC(OpenID Connect)的SSO
学习Identity Server 4的预备知识
使用Identity Server 4建立Authorization Server (1)
使用Identity Server 4建立Authorization Server (2)
使用Identity Server 4建立Authorization Server (3)
使用Identity Server 4建立Authorization Server (4)
使用Identity Server 4建立Authorization Server (5)
使用Identity Server 4建立Authorization Server (6) - js(angular5) 客户端
IdentityServer4(10)- 添加对外部认证的支持之QQ登录
原文:http://www.cnblogs.com/linianhui/p/oidc-in-action-sso-with-js-client.html
.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com
- 基于OIDC(OpenID Connect)的SSO(纯JS客户端)
- 基于OIDC(OpenID Connect)的SSO
- [认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)
- OIDC–基于OAuth2的下一代身份认证授权协议
- OpenID Connect的常见问题与答案
- 基于PHPRPC的单点登录(SSO)的实现
- 基于Cookie的单点登录(SSO)系统介绍
- 【No.1】基于Cookie的单点登录(SSO)
- cas sso oauth openid saml的联系与区别
- 基于CAS的单点登录SSO[5]: 基于Springboot实现CAS客户端的前后端分离
- 日期的三级联动(纯js)
- 欢迎来到OpenID Connect
- Web2.0 , SSO & OpenID
- OpenID Connect:OAuth 2.0协议之上的简单身份层
- OpenID Connect:OAuth 2.0协议之上的简单身份层
- 基于CAS的单点登录SSO[4]: 加入两个CAS客户端测试单点登录
- 基于WEB的 SSO 解决方案
- 基于Tomcat 的SSO实现
- 织梦dede网站搬家后出现/include/templets/default/index.htm Not Found!
- 15算法课程 225. Implement Stack using Queues
- .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
- 牛客练习赛7 A 骰⼦的游戏
- IIS中的 Asp.Net Core 和 dotnet watch
- 基于OIDC(OpenID Connect)的SSO(纯JS客户端)
- strtok函数
- 【骗自己是日更】开始dp习题啦。
- 从建站到seo优化的整体思路
- 织梦dede后台左侧菜单空白不显示解决办法
- mave插件的安装和使用maven创建项目详细解说
- 转载:Spring boot 入门篇(一):构建微服务
- dedecms后台控制常用操作错位解决办法
- 游戏接入微信登录、支付流程2017-12 最新