IdentityServer4主题之登出

Sign-out 登出

IdentityServer的登出就像删除认证cookie一样简单,但是为了完成一个完整的联合签名,我们必须考虑将用户从客户端应用程序中(甚至可能是上游的Identity提供者)登出。

Removing the authentication cookie删除认证cookie

简单的调用HttpContext的SignOutAsync方法就能删除认证cookie,要使用该方法,你需要传递那个使用的认证方案(scheme,默认情况下是IdentityServerConstants.DefaultCookieAuthenticationScheme,除非你更改过它):

await HttpContext.SignOutAsync(IdentityServerConstants.DefaultCookieAuthenticationScheme);

或者你也可以使用IdentityServer提供的这个更为便利的扩展方法:

await HttpContext.SignOutAsync();

通常情况下,应该提示用户登出(意味着需要一个POST),否则攻击者可以将其链接到您的注销页面,从而导致用户自动注销。

Notifying clients that the user has signed-out通知客户端用户已经登出

作为signout这个整体动作的一部分,应该确保客户端应用程序也得到了用户登出的信息,对于有服务端的客户端,IdentityServer提供了对front-channel规范的支持;对于基于浏览器的javascript客户端(例如SPA、React、Angular等),IdentitySever提供了对 session management 规范的支持。

实际上,OIDC定义了三个规范来完成撤销认证这个动作:

  1. Session Management :可选。Session管理,用于规范OIDC服务如何管理Session信息。
  2. Front-Channel Logout:可选。基于前端的注销机制。
  3. Back-Channel Logout:可选。基于后端的注销机制。

其中Session Management是OIDC服务自身管理会话的机制;Back-Channel Logout则是定义在纯后端服务之间的一种注销机制,应用场景不多,这里也不详细解释了。这里重点关注一下Front-Channel Logout这个规范(http://openid.net/specs/openid-connect-frontchannel-1_0.html),它的使用最为广泛,其工作的具体的流程如下(结合Session Management规范):

(上图来自:https://www.cnblogs.com/linianhui/p/openid-connect-extension.html)

在上图中的2和3属于session management这个规范的一部。其中第2步中,odic的退出登录的地址是通过Discovery服务中返回的end_session_endpoint字段提供的RP的。其中还有一个check_session_iframe字段则是供纯前端的js应用来检查oidc的登录状态用的。

4567这四步则是属于front-channel logout规范的一部分,OIDC服务的支持情况在Discovery服务中也有对应的字段描述:

4567这一部分中重点有两个信息:

  1. RP退出登录的URL地址(这个在RP注册的时候会提供给OIDC服务);
  2. URL中的sessionid这个参数,这个参数一般是会包含在idtoken中给到OIDC客户端,或者在认证完成的时候以一个独立的sessionid的参数给到OIDC客户端,通常来讲都是会直接把它包含在IDToken中以防止被篡改。

Front-channel server-side clients 


在front-channel规范中,为了从带有服务端的client上登出用户,identityserver上面的登出页面必须渲染一个<iframe>来通知client客户已经登出。希望被通知的客户端必须设置了FrontChannelLogoutUri 这个配置。IdentityServer跟踪用户登入的那个客户端,并且在IIdentityServerInteractionService (查看详情)上面提供了一个GetLogoutContextAsync 的API,这个API返回一个LogoutRequest对象,它带有一个SignOutIFrameUrl属性,你的登出页面必须呈现为<iframe>(原文是:This API returns a LogoutRequest object with a SignOutIFrameUrl property that your logged out page must render into an <iframe>.我这个翻译很拗口,不知道翻译的对不对,请指正)

Back-channel server-side clients


要通过back-channel规范从服务器端客户端应用程序中签出用户,identityserver中的SignOutIFrameUrl端点将自动触发服务器到服务器的调用,将签名的签出请求传递给客户端。这意味着,即使没front-channel客户端,身份服务器中的“注销”页面仍然必须呈现如上所述的SignOutIFrameUrl。希望被通知的客户端必须有BackChannelLogoutUri配置值集。

Browser-based JavaScript clients

考虑到 session management 规范的设计方式,在identityserver中没有什么特别的东西,需要做的是通知这些客户已经登出。但是,客户端必须在check_session_iframe上执行监控,这是由oidc-client JavaScript library.实现的。

Sign-out initiated by a client application客户端应用发起的登出请求

如果一个登出请求是被客户端应用发起的,那么客户端首先会把用户重定向到end session endpoint。在处理从end session endpoint通过重定向到登出页面这件事可能需要保持一些临时的状态(state)(比如客户端登出的重定向uri)。这个状态或许对于登出页面是有用的,并且state的标志符( the identifier for the state)也通过一个logoutid的参数传递给了logout页面。

interaction service 上面的GetLogoutContextAsync API可以用来加载这个state。返回的LogoutRequest对象上的ShowSignoutPrompt属性指示签出的请求是否已认证过,并且因此它不提示用户签出是安全的。

默认情况下这个state是通过logoutid的值作为一个被保护的数据结构来管理的,通过实现IMessageStore<LogoutMessage>并将其注册到DI,可以在end session endpoint和登出页面之间对这个值做一些持久化的工作。

原文地址:https://www.cnblogs.com/pangjianxin/p/9278812.html

时间: 2024-10-31 14:38:23

IdentityServer4主题之登出的相关文章

PHP+HTML实现登出界面倒计时效果

在WAMP(Windows+Apache+MySQL+PHP)做网站时,通常需要使用Session记录表单登陆用户名和密码等变量,而在登出时需要清除Session.通常我想实现的登出是通过alert提示用户然后header跳转,但下面的代码是通过JavaScript实现的时间倒计时并跳转到主页的效果,主要是看到学校的BT网站等都是这个效果. PS:参考 C# 系统应用之Cookie\Session基础知识及php读取Cookie\Session 代码如下: <?php session_start

MySQL登入登出

1. 我在官网上找的下载链接,但是 下载速度比较慢,用了迅雷7,有些部分来自镜像等,但是应该也没事...下载的是 免安装版 mysql-noinstall-5.1.73-win32.zip 在 百度云(JeeHuanJing) --> MySql_in_Windows 里面,有备份保存. 2. 目录 “... ...\mysql-noinstall-5.1.73-win32\bin” 下,cmd命令: 2.1.开启 MySQL :mysqld --console;  关闭 MySQL :mysq

源代码解读Cas实现单点登出(single sign out)功能实现原理

关于Cas实现单点登入(single sing on)功能的文章在网上介绍的比较多,想必大家多多少少都已经有所了解,在此就不再做具体介绍.如果不清楚的,那只能等我把single sign on这块整理出来后再了解了.当然去cas官方网站也是有很多的文章进行介绍.cas官网http://www.ja-sig.org/products/cas/. ok,现在开始本文的重点内容讲解,先来了解一下cas 实现single sign 的原理,如图所示: 登出原理图 从第一张图中,当一个web浏览器登录到应

Android网络开发实例(基于抓包实现的网络模拟登录,登出和强制登出)

学习Android有几个月了,最近喜欢上了网络编程,于是想通过Android写一些一个小程序用于连接外网.在这里非常感谢雪夜圣诞的支持,非常感谢,给我打开新的一扇门. 1.声明,本程序只能用于西南大学连接外网登录,其他网站需要自己进行抓包测试. 2.声明,本文更多的是关注网络抓包已经,本地构造,如果有什么错误,请尽情指教,非常感谢. 3.声明,最后源代码,以全部上传github,需要的同志可以自行下载,文章结尾会附带链接. 废话不多说,正文开始: 学校官网 第一步,首先需要实现的是登录操作: 当

phpCAS::handleLogoutRequests()关于java端项目登出而php端项目检测不到的测试

首先,假如你有做过cas,再假如你的cas里面有php项目,这个时候要让php项目拥有cas的sso功能,你需要改造你的项目,由于各人的项目不同,但是原理差不多,都是通过从cas服务器获取session_ticket,然后根据ticket去cas服务器获取用户信息并用到项目的登录里面进去. php的cas客户端phpcas能做到这些,但是有个坑就是casphp::handleLogoutRequests()这个函数是用来给检测java端登出时php端也退出,如果你没有看casphp源码的话你不会

博客系统-程序结构-注册登录登出

注册 c判断是否提交了注册数据 是 l如果密码和用户名任一为空 l如果确认密码和密码不一致 m添加用户 c跳转登录页 否 c显示注册页面(提交验证) 登录 判断是否提交了登录数据 c后台验证登录数据->验证类 判断是否在锁定时间内 m判断是否存在登录数据 存在登录用户 重置失败次数和失败登录时间 更新登录时间,ip c设置session的用户名,用户id,权限,角色 c记录日志 c判断跳转(管理首页/跳转到来源页) 跳转 不存在登录用户 记录登录失败时间 跳转登录页 设置session 显示登录

单点登录CAS使用记(六):单点登出、单点注销

单点登出基本上没有啥配置 直接在原来logout的时候,重定向到Cas-Server的logout方法 @RequestSecurity @RequestMapping(value = "loginout", method = { RequestMethod.GET, RequestMethod.POST }) public String loginout(HttpSession session) { session.invalidate(); return "redirec

Struts2学习第六课 实现登录登出功能

关于Struts2请求的扩展名问题: 1).org.apache.struts2包下的default.properties中配置了struts2应用的一些常量 2).struts.action.extension定义了当前struts2应用可以接受的请求的扩展名. 3).可以在struts.xml文件中以常量配置的方式修改default.properties所配置的常量. <constant name="struts.action.extension" value="a

Django 编写博客网站的用户管理部分(采用自有的 django.contrib.auth) 2. 登陆登出和用户信息管理

续前Django 编写博客网站的用户管理部分(采用自有的 django.contrib.auth) 1. 注册部分 项目工具:Python 2.7.11  Django 1.10.2  Bootstrap 3.3.0   IDE:eclipse Pydev 1. 由于Django自带auth, 故仅需编写登录登出的url和template即可 urls常见上篇 template代码如下仅供参考: login 1 {% extends "account_base.html" %} 2 3