【问题标题】:Questions about Native applications and openId Authorization code flow关于 Native 应用和 openId 授权代码流程的问题
【发布时间】:2023-03-21 22:06:01
【问题描述】:

我对我想使用的 OpenId Connect 策略有一些顾虑,但我无法找到有关可能存在的安全问题以及我忽​​略的任何明显问题的详细信息。

目前,我有一个使用 Openiddict 和授权代码流的 OpenId Connect 实现。对于客户端,我有一个使用 react-native-app-auth 的 React-Native 应用程序。

我从关于 SO 的其他问题和 Openiddict 存储库上发布的问题中看到,推荐给第三方提供商(例如 Google)的方法是:Client -> Auth server -> Google Auth -> Auth server - > 客户端/验证服务器代码和令牌交换

但是,从 UX 的角度来看(使用 SPA 或本机应用程序时)似乎更好的方法是在客户端上实现类似于 GoogleSignIn 的东西,并使用 IdToken 或授权代码处理服务器上的身份谷歌。这引入了一个问题,因为之前推荐的流程无法用作整个初始挑战,并且已跳过从 Auth 服务器到 Google Auth 的重定向。

我已经看到,通过不使用授权代码授权,而是实施自定义断言授权,这个问题得到了缓解。这似乎是一种不错的方法,但需要公开自定义授权并在客户端和服务器上以不同方式处理本地和第三方登录的流程。

我提出的解决方案继续使用授权代码流,而不是添加自定义授权类型,客户端只需在 OIDC 授权请求的附加参数中传递第三方标识符“Google”和令牌或授权代码。然后,授权端点可以检测提供者和令牌,执行令牌验证,从中创建用户或主体,并创建授权代码以发送回客户端以进行代码/令牌交换。此流程如下所示:

1.从提供者处获取 id 令牌 Client -> GoogleSignIn -> Client

2。将令牌传递给身份验证服务器并启动代码/令牌交换 客户端 -> 身份验证服务器 -> 身份验证服务器验证 Google IdToken(JWKS、发行者、受众、提供商特定验证等)或交换身份验证代码-> 身份验证服务器 -> 客户端/身份验证服务器代码和令牌交换

这种方法的一个缺点是在服务器端验证令牌的额外跃点。如果令牌是从 GoogleSignIn 返回的,他们自己说它是可以信任的。 https://developers.google.com/identity/protocols/oauth2/openid-connect#obtainuserinfo

我看到一般建议将认证服务器放在客户端和第三方之间,但在这个过程中,服务器仍然在客户端和认证服务器之间,但只有在客户端和第三方进行初始交换之后.

问题,

  1. 总的来说,我在这个流程中遗漏了什么吗?

  2. 在这种情况下,是否需要在服务器端验证令牌?

  3. 有没有更好的方法来解决我完全忽略的问题?

  4. 我是不是把它弄得太复杂了,用户体验不应该是这么大的问题?

  5. 将提供程序和令牌添加到附加参数中是否更有意义?我没有看到通过查询字符串传递它的问题,但这也是我理解授权代码授予的部分原因。

对于我为了简洁而遗漏或遗漏的任何内容,我应该提前道歉。

谢谢。

【问题讨论】:

    标签: react-native oauth-2.0 openid-connect openiddict appauth


    【解决方案1】:

    架构

    我不确定我是否理解用户体验问题 - 您现有的架构感觉非常好。如果您想直接登录 Google,只需在授权重定向中发送 acr_values=google 查询参数,即可绕过任何身份验证选择屏幕。确切的值将取决于 Openiddict 如何表示 Google 身份验证选项,并且一些提供商使用非标准参数,例如 idp。仔细查看OIDC request parameters

    一个关键的 OAuth 目标是授权服务器 (AS) - 在您的情况下为 Openiddict - 保护您的应用免受所有提供商差异的影响,并处理它们的细微差别和供应商特定的行为。然后,您的应用程序也只接收一种类型的令牌,并且只使用简单的代码。例如,Curity AS 支持所有these options,它们都不需要应用程序中的任何代码。

    应用程序和用户体验

    如果用户已经登录,那么正如您所说,启动系统浏览器看起来很不自然,并且会立即将其关闭。

    一个常见的选项是显示同意屏幕或插页式页面以让用户了解情况 - 并且用户单击一个额外的按钮。这对于让密码自动填充工作也很有用。我的code example and blog post 展示了它的外观,当然你可以改进我的基本用户体验。

    离线访问

    我发现这个术语具有误导性,因为刷新令牌最常在用户在那里时使用。您只是在问如何在移动客户端中处理令牌?以这样的行为为目标:

    • API 调用的标准消息,在授权不记名标头中带有访问令牌
    • 标准刷新令牌授予消息以刷新访问令牌 - 例如this code

    另请注意,移动应用可以将令牌保存到应用专用的加密安全移动存储中。这可以提高可用性,例如通过避免每次重新启动应用程序时登录。不过,您应该考虑诸如被盗设备和令牌生命周期等场景。

    【讨论】:

    • 谢谢你。 acr_values 建议是针对我正在寻找跳过“选择”过程的内容。但是,我与 UX 相关的部分问题与客户端到提供者身份验证(如 GoogleSignIn)有关,然后如果我遇到需要离线访问的情况,则将其保留在我的后端。我知道如果在我的授权服务器上启动它会如何工作,但如果在客户端应用程序上完成则不会。
    • 这看起来像是传递刷新令牌和访问令牌或使用身份验证代码。这两个选项都需要在参数中。我看到的 UX 问题是浏览器仍然为该交换打开,但由于不需要用户交互而关闭。对我来说,有两个部分我被困住了:我应该只使用 GoogleSignIn 和类似的解决方案来仅离线访问吗? Google 在 GoogleSignIn 文档中展示了离线访问的示例。将提供者获得的刷新令牌/访问令牌作为参数传递是否安全?
    • 如果传递令牌是安全的,并且为此使用 GoogleSignIn 是有意义的,我可能会冒险寻找一种在不需要用户交互时改进用户体验的方法。
    • 我在上面的答案中添加了几个部分。我可能不完全理解您的情况,但我希望其中一些能给您一两个想法。我的偏好是只从您的应用程序连接到授权服务器。
    • 你帮了很多忙。我的问题很重要,但我现在真的只关心一点。 GoogleSignIn 完全加载到客户端应用程序(我的 AS 还没有 OIDC),并且在选择帐户后,客户端现在拥有可验证的 Google id 令牌。此时,如果我将令牌作为授权代码请求中的参数发送到我的授权端点,我可以验证令牌并将其用作用户身份的断言。如果我在 PKCE 的授权代码授权中执行此操作,我的印象是这是安全的。你同意吗?
    猜你喜欢
    • 2015-12-11
    • 2020-05-17
    • 2018-05-20
    • 2017-06-28
    • 2023-03-27
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多