0

我正在使用 Flutter 中的flutter_appauth包来处理针对 IdentityServer4 的授权代码流,并且无法找到/endsession在 iOS 中调用端点的方法。

为了了解我想要做什么,这是我使用url_launcher包的工作 Android 实现:

    var signOutUrl = '${_endSessionUrl}?id_token_hint=${_idToken}&post_logout_redirect_uri=${AppConfig.oidcCallbackUri}';
    await launch(signOutUrl);

使用相同的代码,iOS 只报告一般PlatformException情况,没有关于原因的其他详细信息,尽管该异常肯定与通过尝试启动 url 完全绕过 AppAuth 有关。

此 GitHub 评论中的解决方案似乎可以使用 OKTA,但是在使用 IdentityServer4 时,我收到以下异常,该异常会立即终止 Flutter 应用程序:

[DEVICE LOG] 2020-04-16 08:55:01.039163-0400  localhost Runner[18007]: (CoreFoundation) *** Terminating app due to uncaught exception 'Attempted to create a token exchange request from an authorization
response with no authorization code.', reason: 'Attempted to create a token exchange request from an authorization response with no authorization code.'

/endsession考虑到我的端点没有返回授权响应,这似乎是有道理的。

无论如何,使用结束会话 URL 调用授权端点的解决方案充其量是一种 hack,但它似乎是这样做的“公认”方式。

我可以找到的所有使用 AppAuth 的文档都说可以通过在应用程序中“忘记”令牌来实现注销,但是由于浏览器保留了身份验证 cookie,因此会自动重新登录。用户没有机会选择其他帐户。

另外值得注意的是,这并不特定于 Flutter、flutter_appauth包或 IdentityServer4。对本机 AppAuth-iOS 包的此评论提出了与上述相同解决方案相同的问题。

绝对必须可以在 iOS 上注销(并因此删除浏览器 cookie),但我完全不知道如何实现它。

4

1 回答 1

2

当您调用授权和交换代码的方法时,需要添加一个名为“promptValues”的附加参数和“登录”值。这样,每次登录时,缓存中都没有值,它总是要求新的登录。

我从这篇文章openid/AppAuth-Android#215来到这个解决方案,其中评论了注销和删除浏览器历史记录和 OpenId 文档

final AuthorizationTokenResponse result =
await appAuth.authorizeAndExchangeCode(
  AuthorizationTokenRequest(
    your_client_id,
    your_localhost,
    promptValues: ['login'],
    discoveryUrl:
    your_discovery_url,
    scopes: [your_scopes],
  ),
);
于 2020-07-14T02:46:01.367 回答