zoukankan      html  css  js  c++  java
  • IdentityServer4【Topic】之登出

    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和登出页面之间对这个值做一些持久化的工作。

  • 相关阅读:
    VS 2010 制作 Windows Service 安装包
    Postback 之后保持浏览器滚动条的位置
    Stream之list转map及问题解决
    List.sort()排序功能
    The content of element type "resultMap"
    MyBatis 一对一,一对多,多对多
    Java Array、List、Set互相转化
    Java流(Stream)操作实例-筛选、映射、查找匹配
    JAVA系列笔记十八之nohup实现后台运行程序
    VSCode汇总
  • 原文地址:https://www.cnblogs.com/pangjianxin/p/9278812.html
Copyright © 2011-2022 走看看