静默刷新在 angular oauth oidc 中不起作用

Silent refresh is not working in angular oauth oidc

我正在尝试在我的 Angular SPA 中静默刷新访问令牌。针对 ADFS 的身份验证已完成。它工作正常,配置如下:

oauthService.configure({
      redirectUri:
        window.location.origin + '/login',
      requireHttps: true,
      scope: 'openid profile email',
      responseType: 'id_token token',
      oidc: true,
      clientId: environment.adfsClientId,
      loginUrl: environment.adfsUrl + '/oauth2/authorize',
      issuer: environment.adfsUrl,
      logoutUrl:
        environment.adfsUrl +
        '/ls/?wa=wsignoutcleanup1.0&wreply=' +
        location.protocol +
        '//' +
        location.hostname + '/login',
      postLogoutRedirectUri:
        window.location.origin + '/login',
    });

    this.oauthService.tokenValidationHandler = new JwksValidationHandler();
    this.oauthService.setStorage(localStorage);
    this.oauthService.timeoutFactor = 0.03; // for faster testing
    this.oauthService.silentRefreshRedirectUri = window.location.origin + '/search';
    this.oauthService.setupAutomaticSilentRefresh();

为了刷新令牌,正在将 iframe 添加到当前页面。一切看起来都不错。并且我已将以下代码添加到 index.html 文件中。

  <script>
    parent.postMessage(location.hash, location.origin);
  </script>

此事件正在 angular-oauth2-oidc.js 的 silentRefreshPostMessageEventListener 中捕获。 但问题是我在该列表中收到的消息是,

MSIS9621: Unable to handle the OAuth authorization request without getting user input.

在 iframe 中生成的 src 标签值如下所示,

https://[adfs domain]/adfs/oauth2/authorize/?response_type=id_token%20token&client_id=af0e4d79-ae9d-4fda-86b3-265d1e86a61e&state=UmtkeUJfNDBCUU1VWkZyeWcubFlldlo3ZHFFbFRuVDI3TnNZUU5FVXJxTXpX&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Fsearch&scope=openid%20profile%20email&nonce=UmtkeUJfNDBCUU1VWkZyeWcubFlldlo3ZHFFbFRuVDI3TnNZUU5FVXJxTXpX&prompt=none

如果我在新选项卡中打开此 URL,我将在 Uri 中获得一个新的访问令牌。

谁能告诉我我做错了什么?

更新

谢谢 Gary Archer 的回答。

我通过在 PowerShell 中执行此代码在 ADFS 中进行了更改,

Set-AdfsResponseHeaders -RemoveHeaders "X-Frame-Options"

没有任何变化。然后我将下面的命令设置为修复该问题。

Set-AdfsResponseHeaders -SetHeaderName "Content-Security-Policy" -SetHeaderValue "frame-ancestors < sources >"

ADFS 似乎正在阻止 iframe 请求并发送 X-Frame-Oprions=DENY header。根据 this post 它可以在 ADFS 2019 中解决。

一个可行的选择是改用刷新令牌,但不建议在 2021 年用于生产 SPA,因为刷新令牌不应存储在浏览器中的任何位置。

值得注意的是,在 2021 年也不真正推荐基于 iframe 的静默更新,因为攻击者可能会在他们自己隐藏的 iframe 上利用它并获取令牌。

2021 年的首选方案是 Back End for Front End 方法,其中 API 处理 SPA 的令牌更新。

AZURE AD API 驱动方法

继续的方法是插入 API 并将其指向 Azure AD 端点。这将使令牌远离浏览器,而浏览器将只使用 SameSite cookie。

Curity 的以下解决方案演示了这种方法,API 可以指向任何授权服务器。不过这需要一些消化。