【问题标题】:Have angular-oauth2-oidc retrieve access token from other tabs让 angular-oauth2-oidc 从其他选项卡检索访问令牌
【发布时间】:2018-10-26 11:20:00
【问题描述】:

我将 angular-oauth2-oidc 库与隐式流(与 IdentityServer4 服务器)结合使用。我已经成功设置the Silent Refresh suggestion from the docs

这是我在包装服务中引导事物的方式:

private userSubject = new Subject<User>();

constructor(private config: ConfigService, private oAuthService: OAuthService)
{ }

// Called on app load:
configure(): void {
    const config: AuthConfig = {
      issuer: this.config.getIdentityUrl(),
      logoutUrl: this.config.getIdentityUrl() + '/connect/endsession',
      redirectUri: window.location.origin + '/',
      silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
      clientId: 'my_client_id',
      scope: 'openid profile my_api',
      sessionChecksEnabled: true,
    };

    this.oAuthService.configure(config);
    this.oAuthService.tokenValidationHandler = new JwksValidationHandler();

    this.oAuthService
      .loadDiscoveryDocumentAndLogin()
      .then((_) => this.loadUserProfile());

    this.oAuthService.setupAutomaticSilentRefresh();
}

private loadUserProfile() {
  this.oAuthService.loadUserProfile()
    .then((userProfile) => {
      const user = new User(userProfile['name']);
      this.userSubject.next(user);
    });
}

但是,如果我在新选项卡中打开应用程序,用户也会被重定向到 IdentityServer(并立即返回我的应用程序)。

我的问题:我能否让库从同源的其他选项卡中检索现有的访问令牌(以及可选的用户信息),以防止重定向?(首选,因为它不需要Ajax 调用。)

或者,在我们将某人发送到 IdentityServer 之前,是否有一种简单的方法可以尝试使用静默刷新机制?

【问题讨论】:

    标签: angular typescript identityserver4 angular-oauth2-oidc


    【解决方案1】:

    首先:我不知何故认为sessionStorage 适合令牌,而localStorage 应该始终 避免使用。但这是来自另一个涉及更强大(刷新)令牌的项目,并且通过隐式流程,我只有短暂的访问令牌,所以localStorage 也没有sessionStorage 更不安全。最后:根据您自己的具体情况评估攻击向量:“这取决于”。

    我没有提到我有这个想法,the other answer 帮助我重新思考事情并考虑使用 localStorage。这实际上是一个很好的解决方案。

    事实证明,该库已内置支持使用 localStorage 作为令牌和其他数据的后备存储。起初虽然我在尝试:

    // This doesn't work properly though, read on...
    this.oAuthService.setStorage(localStorage);
    

    但是这种引导方式不适用于我的情况,请参阅issue 321 on the libraries GitHub issues list 了解我的登录信息。从该线程重复解决方案(或解决方法?),我通过在应用程序模块的providers 中执行此操作来解决问题:

    { provide: OAuthStorage, useValue: localStorage },
    

    现在库将正确使用 localStorage,新标签(甚至新窗口)会自动选择它。


    作为脚注,如果出于安全原因不想使用localStorage,您也可以提供自己的存储,只要它实现OAuthStorage 接口即可。然后,您自己的实现可以使用任何可用的选项卡间通信技术来“询问”来自其他选项卡的数据,如果需要,可以回退到 sessionStorage。

    【讨论】:

      【解决方案2】:

      有一个解释,为什么它总是去 IdentityServer 来澄清当前用户,它是你展示的代码。

      每次打开选项卡时,您的应用都会启动,并执行上面的代码。现在 - 所有这些支持 SPA'a 和 Implicit 流的 oidc 库都将用户数据 (access_token ... ) 存储在浏览器会话存储中。通过打开一个新选项卡,您将拥有一个新会话。

      我的意思是 - 在尝试对 Identity Server 进行身份验证之前,您需要做一些事情。我指的是将所有用户信息从Session storage 移动到Local storage。然后,位于同一应用程序(分别为同一来源)下的选项卡将具有共享的Local storage

      所以您在应用程序开始时的流程应该是这样的:

      1. 检查本地存储以获取用户信息
      2. 如果存在,请设置身份验证服务(包括静默刷新),但不要尝试登录。并将数据移动到会话存储(不确定是否需要,但我猜图书馆会在那里寻找)
      3. 如果没有 - 登录,然后将数据从会话存储移动到本地
      4. 当然,在静默更新回调中,您必须更新本地存储中的值(它们应该由会话中的库更新)。
      5. 最后,但同样重要的是 - 在注销时,您必须进行清理。

      对我来说,这对你来说似乎是一个解决方案。现在 - 由您决定是否值得。

      PS:只是澄清一下-我还没有尝试过。我不能保证它会起作用,但是按照事件的顺序,它应该会起作用。

      【讨论】:

      • 感谢您的回答,它引导我朝着正确的方向前进!
      猜你喜欢
      • 2021-11-14
      • 2019-02-01
      • 1970-01-01
      • 2021-07-04
      • 1970-01-01
      • 2018-06-30
      • 2020-10-12
      • 2019-04-23
      • 1970-01-01
      相关资源
      最近更新 更多