基于Identity Server4的OAuth 2.0/Open ID授权总结(5)- Logout

OAuth2.0/OpenID 的Logout包括Authorization Server的Logout和Client的Logout。

Authorization Server的Logout

Authorization Server的Logout其实很简单,仅仅是简单的清除Login Cookie即可。可以调用Identity Server 4所提供的扩展方法SignOutAsync来实现。

Client的Logout

在Logout的过程中最复杂的是Client的Logout,因为Authorization Server与所有的Client之间其实构成了一个分布式系统(如下图)。Authorization Server Logout后需要通知所有Client Logout信息,然后所有Client相继Logout.

OpenID Connect协议中定义了三种方式来通知Client Logout。

Front-channel

这种方式的实现原理是每个Client在Authorization Server上注册一个用于Logout的页面Url(通过FrontChannelLogoutUri设置)。当Authorization Server Logout后,在Logout页面上,将所有登录过的Client的Logout页面也iframe的形式嵌入。这样所有Client的Logout页面会被访问,最终所有Client的Login状态被清除。

 这种方式主要适用于Server side client, 理论上SPA应用应该也可以实现这种方式。

这种方式最终是通过浏览器发送请求给Server端来Logout.所以称为Front-Channel.

Back-channel

相较于Front-Channel, Back-Channel是通过Authorization Server的后端直接调用Client的接口来清除某个用户的登录状态。这种方式没怎么使用过。目前还有一点没弄明白其Logout的原理。(比如MVC Client的认证状态是通过cookie管理,那这种方式下,MVC Client如何如清除某个用户的Cookie呢,毕竟Cookie是存在浏览器端的,而Back-Channel方式是Authorization Server与MVC Client之间的交互,和用户的浏览器无关。这里需要再研究一下。)

Session Management

SPA应用的Logout基本是靠轮询,即周期性的检测用户登录状态是否发生变化。如变化则触发重新认证。但是OpenID协议设计了一个巧妙的方法来避免周期性轮询Authorization Server造成网络资源浪费。如下图:

详细过程如下:

1. 在用户登录后,Authorization Server会向生成一个session id写入cookie idsrv.session.(改cookie的origin为authorization server所在域)

2. 在redirect url的重定向请求中,Authorization Server会在Url中添加一个名为session_state的Query string。该session_state的生成算法为Base64(SHA256(clientId+clientOrigin+sessionId+salt)),salt 

Client会再redirect url所在页面中将session_state存入session storage(origin 为client所在域)

3. 在SPA页面中,需要加载两个iframe:client iframe(origin 为client所在域)和check session iframe(origin为authorization server 所在域)

4. 在client iframe中,会周期性的从session storage中取出session_state,然后通过PostMessage发送给check session iframe.

5. check session iframe收到来自client iframe的message后,会从authorization server域中取出cookie idsrv.session(sessinId), 然后用第2步中的算法重新生成session_state。

6. check session iframe通过比较第5步生成的session_state和client iframe发送过来的session_state可以知道SPA当前session是否发生变化。然后通过PostMessage将结果(changed或unchange)发送给client frame

7 如果第6步结果为changed, client iframe收到后会触发重新认证。

说明:第一步中的cookie: idsrv.session, 在用户Logout或者切换用户后会发生变化。因此可以在第6步中检测到。

基于Identity Server 4的实现

1. Front Channel Logout

只需在定义Client时为其设置FrontChannelLogoutUri,然后再Client端处理该请求是实现Client Logout的逻辑

2. Back Channel Logout

跟Front Channel Logout一样,只需在定义Client时为其设置BackChannelLogoutUri,然后再Client端处理该请求是实现Client Logout的逻辑

3. SPA Client Logout

oidc-client 提供实现。无需额外实现。

原文地址:https://www.cnblogs.com/Code-life/p/13452874.html