oidc-client CheckSessionIFrame正确触发一次,然后每隔一段时间失败一次

oidc-client CheckSessionIFrame fires properly one time, then fails ever interval thereafter

本文关键字:一次 然后 一段时间 失败 CheckSessionIFrame oidc-client      更新时间:2023-09-26

这实际上可能不是Identity Server或oidc-client的问题,但我很难确定问题所在。我在一个Aurelia应用程序中通过System.js运行这个,所以这个问题可能来自这些外部库之一。

CheckSessionIFrame.start(session_state)中,我们有以下代码:

this._timer = window.setInterval(() => {
  this._frame.contentWindow.postMessage(this._client_id + " " + this._session_state, this._frame_origin);
}, this._interval);

第一次间隔触发时,似乎没有问题。iFrame的contentWindow存在(如预期的那样),并且调用postMessage方法没有问题。两秒钟后,当间隔再次触发时,this._frame.contentWindow是未定义的—所以我最好的猜测是iFrame不知怎么地死亡了。同样,这可能不是oidc-client的问题,但我正在寻找有关可能导致这个iFrame死亡的任何有用的指导(也许在内部它可能在脚本上死亡?),例如oidc-client缺少必要的配置值。

要让oidc-client使用silent renew,您需要将aurelia-app放置在不是body的元素上,因此您可以将元素放置在body内而不是aurelia-app的外部。

这允许你把IFrame放在Aurelia -app之外,这样可以防止Aurelia引导程序吃掉它,并让oidc-client独立于Aurelia运行。

编辑

根据你的评论,以及我的一点记忆刷新,我重新措辞/澄清:

会话检查器和静默更新功能是独立工作的。您可以在会话检查器启动手动调用之前静默续订。您还可以启动会话检查器,而不执行任何静默更新。它们只是方便一起使用,但这是它们唯一的关系。

我假设您使用混合流并具有RP和OP iframe的标准会话检查器实现,其中OP iframe位于check_session.html页面中,RP iframe位于您的aurelia应用程序中的某个地方。在我的一个项目中,我在index.html中有RP iframe,在aurelia应用程序元素之外,因此它独立于aurelia工作。但我想它不一定非得在那里。

当您将RP iframe的src属性设置为check_session.html的位置时,会话检查器开始,其中session_state, check_session_iframeclient_id在哈希之后。

check_session.html页面将通过启动周期性轮询来响应,并在状态发生变化时向aurelia应用程序的window发送消息。

从你的aurelia应用程序,你听这个消息,并做signinSilent()调用,如果它表明一个改变的状态。在 silent_renewal .html页面中,您使用signinSilentCallback()

对其进行响应

所有这些都到位了,当你启动会话检查器时,它真的不重要。把它藏在某个特性中,最后加载那个特性。

在应用程序启动期间,您只需要担心两件事:

  • 检查window.hash#code开始,如果它做,则调用signinRedirectCallback(code)
  • 如果没有,就立即调用signinSilent()(这样可以让您检查的东西最少)

然后在其中任何一个完成后,执行getUser()并检查它是否为null或expired属性=== true。如果是上述任何一种情况,执行signinRedirect()。如果没有,你的用户身份验证,你可以让aurelia应用程序做它的事情,并启动会话检查器等。

我肯定会而不是将初始身份验证检查放在aurelia-app中的index.html上。因为如果aurelia恰好在oidc检查完成之前完成加载,则该过程将失败。您还可能希望将user对象(和UserManager)存储在一些缓存/服务/其他类型的单例类中,以便您可以轻松地从aurelia应用程序与oidc进行交互。