使用 Identity Server 4 在 Ionic 3 中静默更新

Silent Renewal in Ionic 3 with Identity Server 4

所以我正在尝试在 ionic 3 应用程序中实现静默更新,我仍在了解整个事情,所以我会尽量描述性强,如果我错了请纠正我。

身份验证

我使用 Implicit 流程进行身份验证,使用 In App Browser

  1. 用户被重定向到认证服务器页面
  2. 身份验证成功后,我检索了 id-token 和 access-token

据我了解,id-token 用于身份验证,access-token 用于使用 API 进行授权。

我已经按照 this article 帮助我为我的身份服务器设置了这个(特别是 "Deploy to Mobile Device" 部分)。

正如文章中所做的那样,我正在使用 angular-oauth2-oidc 来帮助我存储有关重定向链接、发布者等的信息...

我已尝试通过 3 种不同的方式实现此目的,其中 2 种有效,但我不明白如何检索新的 access-tokenid-token,以及最后一种 return 是一个错误。他们每个人都给我留下了问题。

第一:oauthService

angular-oauth2-oidc 库有一个 silentRefresh() 方法,this github MD 非常模糊地描述了如何使用隐藏的 iframe 使用它,所以我几乎不明白它是如何工作的。我在同一目录中创建了一个 silent-refresh.html 页面,但使用 http://localhost:8000/silent-refresh.html return 的 404。服务端调用silentRefresh()方法重新认证成功,但客户端请求超时,如MD文件所述,iframe有问题

问题 1:库是否创建了一个新的 iframe,然后等待对 http://localhost:8000/silent-refresh.html 页面的响应但从未找到,所以我从未收到响应?如何继续取回我的代币?

第二:iframe

所以在这里我按照 this article 创建一个 iframe 并将其添加到 body。我创建自己的 url(类似于 silentRefresh() 方法创建的),并将其分配给 iframesrc。同样在服务器端,一切都很好,它尝试将 return 令牌 http://localhost:8000.

public startRenew(url: string) {
        this._sessionIframe.src = url;

        return new Promise((resolve) => {
            this._sessionIframe.onload = () => {
                resolve();
            }
        });
}

问题二:如何取回令牌?因为它不会自动更新我的令牌,而且我不明白上面的代码是如何做到的。

第三:在应用程序浏览器中 我认为这会很好,因为我已经知道如何使用 In App Browser 处理请求。因此,我尝试使用与第二部分中的 iframe 相同的 url。然而,这 return 是服务器端的一个错误:prompt=none was requested. But user is not authenticated.,表明服务器无法找到会话,因此它不知道是谁在请求令牌更新。

问题 3:除了我犯了一个错误之外,是否有其他具体原因导致它不起作用?

注意:写这篇文章的时间比预期的要长,稍后会对其进行编辑。

oAuthService

所以我查看了静默刷新的 the implementation,看看它做了什么。它会创建一个带有默认 ID 的 iframe,除非您覆盖它。这消除了很多关于实际发生的事情的困惑。

我犯的下一个错误是将 silent-refresh.html 文件放在 src/ 文件夹中,这使得 iframe 无法访问它。相反,文件应该放在 www/ 文件夹中。

然后在 iframe 中,我不断收到 net::ERR_CONNECTION_REFUSED 错误。这是由于 CORS,通过编辑 Authentication Server 上的 Config.cs 文件中的 Client 解决: AllowedCorsOrigins = { "http://localhost:8100", "http://<ip>:8100/", "http://<ip>:8100/silent-refresh.html" },

警告:一旦我想在浏览器 (ionic serve) 中使用它或在我的设备上使用 [=23= 进行模拟,这就不起作用了],这些使得 root url return 类似于 http://<ip>/。但是一旦 运行 与 ionic cordova run android(没有标志),window.location.href 将 return file:///<example>/<something>/index.html,使用这种路径 (file:///<example>/<something>/silent-refresh.html) 作为重定向 url 导致 ERR_UNSAFE_REDIRECT 错误显示在 iframe 中。

也许 silentRefresh() 是 Angular 唯一的解决方案?

在应用程序浏览器中

导致原始错误的错误是在创建浏览器时将 clearsessioncacheclearcache 设置为 yes,导致会话被擦除,因此身份验证服务器没有知道是谁了,现在变成这样:

const browser = window.cordova.InAppBrowser.open(oauthUrl, '_blank',
     'location=no, hidden=yes'
);

http://localhost:8100 的常规 redirect url 可用于使用新令牌捕获请求。 silent-refresh.html 页面不需要。

这是创建 oauthUrl:

的代码
buildOAuthRefreshUrl(nonce): string {
    return this.oauthService.issuer + '/connect/authorize?' +
      'response_type=id_token%20token' +
      '&client_id=' + this.oauthService.clientId +
      '&state=' + nonce +
      '&redirect_uri=' + encodeURIComponent(this.oauthService.redirectUri) +
      '&scope=' + encodeURI(this.oauthService.scope) +
      '&nonce=' + nonce +
      '&prompt=none';
}

其余代码与 originally mentioned article

几乎相同