关于Native applications和openId Authorization code flow的问题

Questions about Native applications and openId Authorization code flow

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

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

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

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

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

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

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

2。将令牌传递给 auth 服务器并启动代码/令牌交换 Client -> Auth Server -> Auth server Verify Google IdToken (JWKS, issuer, audience, provider specific validation, etc. ..) 或交换授权代码 -> 授权服务器 -> Client/Auth 服务器代码和令牌交换

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

我看到一般建议将认证服务器放在客户端和第三方之间,但在这个过程中,服务器仍然在客户端和认证服务器之间,只是在客户端和第三方的初始交换之后-派对。

问题,

  1. 总的来说,这个流程是不是遗漏了什么?

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

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

  4. 我是不是把它弄得太复杂了,UX 不应该那么重要吗?

  5. 与其将提供者和令牌添加到附加参数中,不如将其传递到 post 请求的正文中是否更有意义?我没有看到通过查询字符串传递它的问题,但根据我的理解,这也是授权代码授予的部分原因。

对于我为简洁起见而遗漏或遗漏的任何内容,我深表歉意。

谢谢。

建筑

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

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

APPAUTH 和 UX

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

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

离线访问

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

  • 用于 API 调用的标准消息,在授权承载中使用访问令牌 header
  • 用于刷新访问令牌的标准刷新令牌授予消息 - 例如 this code

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