在上一篇基于OIDC的SSO的中涉及到了4个Web站点:

  1. oidc-server.dev:利用oidc实现的统一认证和授权中心,SSO站点。
  2. oidc-client-hybrid.dev:oidc的一个客户端,采用hybrid模式。
  3. oidc-client-implicit.dev:odic的另一个客户端,采用implicit模式。
  4. 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,并交给浏览器去发起了请求。

  1. /account/js:我自己扩展的,后面介绍其用途,目前暂时忽略它。
  2. /.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 in Action] 2. 基于OIDC(OpenID Connect)的SSO(纯JS客户端)的更多相关文章

  1. [OIDC in Action] 3. 基于OIDC(OpenID Connect)的SSO(添加Github OAuth 2.0的支持)

    在上上一篇基于OIDC的SSO的登录页面的截图中有出现QQ登录的地方.这个其实是通过扩展OIDC的OpenID Provider来实现的,OpenID Provider简称OP,OP是OIDC的一个很 ...

  2. [OIDC in Action] 1. 基于OIDC(OpenID Connect)的SSO

    在[认证授权]系列博客中,分别对OAuth2和OIDC在理论概念方面进行了解释说明,其间虽然我有写过一个完整的示例(https://github.com/linianhui/oidc.example) ...

  3. asp.net core系列 56 IS4使用OpenID Connect添加用户认证

    一.概述 在前二篇中讲到了客户端授权的二种方式: GrantTypes.ClientCredentials凭据授权和GrantTypes.ResourceOwnerPassword密码授权,都是OAu ...

  4. 第11章 使用OpenID Connect添加用户身份验证 - Identity Server 4 中文文档(v1.0.0)

    在本快速入门中,我们希望通过OpenID Connect协议向我们的IdentityServer添加对交互式用户身份验证的支持. 一旦到位,我们将创建一个将使用IdentityServer进行身份验证 ...

  5. IdentityServer4 实现 OpenID Connect 和 OAuth 2.0

    关于 OAuth 2.0 的相关内容,点击查看:ASP.NET WebApi OWIN 实现 OAuth 2.0 OpenID 是一个去中心化的网上身份认证系统.对于支持 OpenID 的网站,用户不 ...

  6. [认证授权] 5.OIDC(OpenId Connect)身份认证授权(扩展部分)

    在上一篇[认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)中解释了OIDC的核心部分的功能,即OIDC如何提供id token来用于认证.由于OIDC是一个协议族,如果 ...

  7. [认证授权] 5.OIDC(OpenId Connect)身份认证(扩展部分)

    在上一篇[认证授权] 4.OIDC(OpenId Connect)身份认证(核心部分)中解释了OIDC的核心部分的功能,即OIDC如何提供id token来用于认证.由于OIDC是一个协议族,如果只是 ...

  8. [认证授权] 4.OIDC(OpenId Connect)身份认证授权(核心部分)

    0 目录 认证授权系列:http://www.cnblogs.com/linianhui/category/929878.html 1 什么是OIDC? 看一下官方的介绍(http://openid. ...

  9. [认证授权] 4.OIDC(OpenId Connect)身份认证(核心部分)

    1 什么是OIDC? 看一下官方的介绍(http://openid.net/connect/): OpenID Connect 1.0 is a simple identity layer on to ...

随机推荐

  1. CSS3实现3D旋转相册

    静态效果图: 代码如下: <!doctype html><html lang="en"><head> <meta charset=&quo ...

  2. 使用WinDBG调试查看C#内存转储文件

    有时候我们想查看一个正在运行的程序内存中的数据,可以在任务管理器将内存状态保存为转储文件,并使用WinDBG验证,这里我们来试试: 0.安装WinDBG 1.首先写个代码用来测试 一个class pu ...

  3. Node.js之异步流控制

    前言 在没有深度使用函数回调的经验的时候,去看这些内容还是有一点吃力的.由于Node.js独特的异步特性,才出现了"回调地狱"的问题,这篇文章中,我比较详细的记录了如何解决异步流问 ...

  4. C# 剪贴板中文乱码问题

    最近写了个小工具.主要功能是生成一些数据,然后一键复制,最终粘贴到需要的地方. 本来一切正常的,可是当把工具拿给朋友使用时,却被告知粘贴出来的数据是乱码.当时第一时间想到是区域问题(朋友是台湾人),不 ...

  5. 深入理解Java虚拟机--下

    深入理解Java虚拟机--下 参考:https://www.zybuluo.com/jewes/note/57352 第10章 早期(编译期)优化 10.1 概述 Java语言的"编译期&q ...

  6. 在C#中winform程序中应用nlog日志工具

    在C#中winform程序中应用nlog日志工具,配置文件简单应用. 文件名 nlog.config,请注意修改属性为"始终复制",发布时候容易遇到不存在文件的错误提示. 通过Nu ...

  7. Java基础总结--异常处理机制

    ----异常的概述-----1.异常,就是不正常的现象,可能发生在编译期间也可能发生在运行期间2.可能会出现不同的异常,进而在Java中对其描述封装为类--在这些异常类中抽取其共性的东西(异常发生的位 ...

  8. ASP.NET中登录时记住用户名和密码(附源码下载)--ASP.NET

    必需了解的:实例需要做的是Cookie对象的创建和对Cookie对象数据的读取,通过Response对象的Cookies属性创建Cookie,通过Request对象的Cookies可以读取Cookie ...

  9. idea的debug调试快捷键

    1 2 3 4 5 6 7 8 9 10 F9            resume programe 恢复程序 Alt+F10       show execution point 显示执行断点 F8 ...

  10. HTML5网站大观:15个精美的 HTML5 单页网站作品欣赏

    HTML5 是现在Web开发领域的热点,更多的开发人员开始使用HTML5来开发交互性强.效果出众的Web应用和游戏.今天,本文收集了15个精美的 HTML5 单页网站作品,让大家感受一下 HTML5 ...