在 Angular 中使用 IdentityServer4 + oidc-client-js 在空闲时注销用户

Posted

技术标签:

【中文标题】在 Angular 中使用 IdentityServer4 + oidc-client-js 在空闲时注销用户【英文标题】:Log out user when idle using IdentityServer4 + oidc-client-js in Angular 【发布时间】:2019-12-27 15:36:56 【问题描述】:

在我的应用程序中,我有一个超时功能,因此当用户空闲 X 分钟时,我想从 Identity Server 注销。

我的第一次尝试是在不让用户导航到注销控制器的情况下手动创建调用。

这段代码看起来像这样(Angular + TS):


      this.userManager
        .createSignoutRequest( id_token_hint: this.user && this.user.id_token )
        .then(signout_request => 

          this.http
            .get(signout_request.url, 
              responseType: 'text',
              headers: new HttpHeaders().set(InterceptorSkipHeader, '') // Ignores token http-interceptor
            )
            .subscribe(_ => 
              this.userManager.removeUser().then(_ => 
                window.location.href = '/timeout'; // Navigate to page that informs user has been timed out
              );
            );
        );

我可以看到它使用 id_token_hint 和正确的 redirect_url 进入 endsession 端点,但是当我尝试重新登录应用程序时,它给了我一个令牌,而没有再次询问我的凭据,这违背了它的目的。

oidc-client-js 库中的常规注销功能可以正常工作。


    this.userManager
      .signoutRedirect()
      .then(res => 
        if (!environment.production) 
          // console.log('Redirection to signout triggered.', res);
        
      )

唯一需要注意的是,我想向用户提供其他信息,说明他们由于不活动而超时,但我不确定如何操作。

此函数接受 post_logout_redirect_uristate 作为参数,但我无法在我的 IdentityServer 上成功获取它们(我还是个 .Net 新手)。

这是错误的方法吗?我是否应该使用 /timeout 路由之类的方式将用户导航回我的 Angular 应用程序以显示此消息?

感谢您的意见

【问题讨论】:

【参考方案1】:

AFAIK 不支持以这种方式调用结束会话端点 - 它必须是***导航,因为它可能涉及呈现 UI。执行这样的 CORS 请求时不会发送任何 cookie。

更好的选择可能是在登录请求中使用max_age 授权端点参数,并在生成的id_token 中检查auth_time 以确保它不比您想要的旧。这样,如果他们在您提供的时间段内通过身份验证,您只会获得一个新令牌,但您不必担心显式注销用户。

post_logout_redirect_uri 确实是在用户退出后将用户带回应用程序内某个位置的正确方法。这些 URI 必须针对客户端进行预注册。

【讨论】:

感谢您的意见。如果您能澄清一下,我有一个问题:在这种情况下,如果我也使用静默续订,我会在每次续订时获得新的时间吗?或者这是否只适用于,比方说,让用户只能使用令牌 1 天或 8 小时或类似的时间 如果使用静默续订 (prompt=none) 和 max_age=n,那么如果超过年龄,您将收到 error=login_required 作为响应,并且必须提示进行交互式身份验证,这反过来会将auth_time 更新为now() 谢谢,我会试试看。虽然这不能回答我原来的问题,但我相信这是真正解决问题的方法。再次感谢您的宝贵时间。 @Narshe 你找到解决方案了吗,你能用代码展示一个例子吗?? @mackie 你能提供一个示例代码吗?我也面临同样的问题

以上是关于在 Angular 中使用 IdentityServer4 + oidc-client-js 在空闲时注销用户的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 @angular/upgrade 在 Angular 1 应用程序中使用 Angular 2 组件

如何在 Angular 6 中使用 angular-timelinejs3?

在 Storybook 中使用 @angular-redux/store 测试 Angular

Angular - 在服务和组件中使用管道

在 Angular 5 和 AOT-Build 中使用 @angular 编译器时出错

在Angular 2+项目中使用AngularJS Material组件