通过 JWT API 在 android 应用中设计身份验证

Posted

技术标签:

【中文标题】通过 JWT API 在 android 应用中设计身份验证【英文标题】:Designing authentication in android app through JWT API 【发布时间】:2021-11-01 23:09:58 【问题描述】:

背景

几年前,我们在 ASP.Net Core 2.2 中开发了一个 CMS,用于公司内部的日常工作。它拥有数百名用户,我正在考虑为其添加一个 android 应用程序。 android 应用程序应主要用作 ASP.Net 控制器中现有逻辑的前端。我期望拥有的 Android 应用的好处是:

更好的用户体验 用户不必为每个会话输入密码(ASP.Net 页面在 20 或 30 分钟不活动后将其注销) 推送通知等

现有基础设施

CMS 已经有一个 API (JWT),可供多个后端服务使用,并且可以通过 android 应用轻松扩展以供每个用户使用。不幸的是,我一般不是专业的开发人员,尤其是对 Java 很陌生,所以请耐心等待我,因为我正在寻求有关如何处理 android 应用程序 (Java) 中的身份验证的一般建议。

我读到了 curity.id 和类似的东西,但是 IMO 这对整个项目来说有点矫枉过正,并且还需要对已经运行良好的 ASP.Net 网站进行重大更改。

现在我的问题是,以下做法是否可以接受:

    当用户第一次打开应用程序时,我会询问他的用户名和密码(以及可选的第二个因素)。 我向 CMS 的 API 发出一个 http 请求,以便对用户进行身份验证并在成功验证时取回 JWT 令牌。 JWT 令牌以某种方式存储(例如 SQLite DB),并用于向 API 发出的后续请求。 由于 JWT 令牌的生命周期也被限制为几个小时,并且目标是保持应用程序运行而不会一直提示用户输入凭据,因此我还需要以某种方式将密码存储在android 设备上的应用程序或数据库。这实际上是最让我困惑的部分,我不知道如何以安全的方式存储密码,因此它可能会再次用于身份验证请求。 (我知道,如果用户使用第二个因素,除了每次令牌过期或排除设备时都要求第二个因素外,别无他法,但这不应该在这个范围内问题)

因此,如果总体上可以接受,以及如何处理第 4 点的最佳方法,我将很感激能对这种方法做出一些判断。

非常感谢

【问题讨论】:

"由于 JWT 令牌的生命周期也被限制为几个小时,并且目标是保持应用程序运行而不会一直提示用户输入他的凭据,我需要也以某种方式将密码存储在应用程序或 android 设备上的数据库中。" - 不要那样做。如果系统使用 OAuth/OIDC,则存储刷新令牌并使用它来发布新的访问令牌。在设备上以明文形式存储密码是有风险的。 100% 同意@Turing85 使用刷新令牌。您根本不应该保存/存储用户密码。没必要,只会带来安全风险 谢谢你们 - 我会阅读有关刷新令牌的信息(不知道存在这样的事情)。 【参考方案1】:

不存储密码

如果存储(并经常发送)密码,您就违背了令牌的全部目的。令牌本身作为替代主要身份验证的一次性方式存在(但在密码学上足够强大,可以在不降低系统安全性的情况下替换它)。

简单:使用长标记

创建一个新的身份验证 API(或在现有的基础上添加一些参数)以使移动 APP 需要一个持久令牌(例如 6 个月)。如果您随后将此令牌存储在设备的SecureStorage 中,您可以确信它无法从那里提取。

请记住,使用此解决方案,您将失去对身份验证的控制。这不是最佳实践,但对于仅使用一个令牌的现有 JWT 基础架构而言,这是最容易采用的解决方案。

推荐:创建一个更新令牌系统

一旦您发布了令牌,您就无法撤销它。因此,“长令牌”解决方案引入的主要问题是,如果设备丢失,则无法取消身份验证。这可以通过更新令牌来解决:

您创建一个身份验证 API,在确认身份验证后,它会创建一个唯一的 sessionId,将其存储在数据库中,并发出一个包含 sessionId 以及其他信息的特殊令牌。这称为更新令牌。此特殊令牌只能用于 exchange API 然后您创建一个交换 API,该 API 需要一个 更新令牌 来交换一个普通的 令牌(它可以具有您当前令牌所具有的相同属性)。此 API 将始终检查更新令牌中的 sessionId 是否在数据库中仍被标记为活动,否则不会发出正常令牌。

这种方法允许您拥有很长的过期令牌,但仍然可以控制远程注销应用程序(通过在数据库中将sessionId 屏蔽为停用),甚至监控应用程序的使用频率。

【讨论】:

以上是关于通过 JWT API 在 android 应用中设计身份验证的主要内容,如果未能解决你的问题,请参考以下文章

如何通过zuul或任何api网关调用安全的微服务端点

REST API 发送 JWT

Google Pay API - 在没有 JWT 的情况下向 Google Pay 应用程序插入通行证

在 Spring Boot 微服务的 JWT 令牌生成中设置两个主题

在每个 API 请求中传递 JWT 令牌

如何在 Laravel 5.1 中设置 JWT Token 的过期时间