api – OAuth2一次性授予注册和丢失密码

我们正在构建一个主要由JS前端使用的REST服务.验证的主要方法是OAuth2.

我们使用密码授予类型进行登录,但我们遇到的一件事是:我们如何设计“丢失密码”功能.通常,这是通过允许用户输入他们的电子邮件地址然后向他们发送一次性令牌来完成的.

这需要以下内容:

>未经过身份验证的端点.像POST / lost-password这样的东西,接受电子邮件地址.我意识到这不是很安宁,但我可以忍受.然后,此端点使用一次性令牌向用户发送电子邮件.
>在用户使用令牌返回前端之后,我基本上希望允许客户端将该令牌交换为OAuth2承载令牌.

所以我没有在规范中看到真正做到这一点的grant_type.我的问题是:

这是我应该扩展OAuth2并创建一个新的grant_type(具有OAuth2支持的东西)的情况,该grant_type特定用于与OAUth2访问令牌交换一次性身份验证令牌吗?

最佳答案

TL;DR I would think twice on going with the creation of a new grant_type extension and instead would consider the use of existing flows and OpenID Connect in order to replace the usage of ROPC with the implicit grant flow which would allow you to get access tokens based on an already existing authentication session and in this way saving the user to re-enter their credentials.

无聊的理论

这种情况超出了OAuth 2.0的范围;如果不包含资源所有者密码凭证授权(ROPC),那么用户身份验证的整个主题可能被认为是超出范围的,而ROPC似乎在规范中的内容和范围之外混淆了水域.

但是,您应该考虑将ROPC作为存储用户密码的应用程序的快速迁移路径引入,以便在用户脱机时起作用,而不是解决用户身份验证主题的方法.

即使是明确关注用户身份验证的OpenID Connect也不会指定重置密码机制,因为这是特定于一种类型的用户凭据.这通常作为身份提供者的实现细节.

看看替代品

选项A易于实现

我假设你考虑过,但是想避免使用以下选项(A),这些选项不需要交换令牌和/或自定义授权类型:

>用户请求密码重置;
>身份提供商通过电子邮件发送密码重置代码URL;
>用户访问URL并更改密码;
>用户使用新密码登录应用程序(ROPC)并获取访问令牌;

这将适用于您当前的方法,而无需扩展或触摸与OAuth2相关的任何内容;但是,这意味着用户必须在实际完成重置过程密码后重新输入其凭据.

选项B它可能更优雅

另一个选项(B)更复杂,但仍然无需扩展协议,并且还强化了你提到的/ lost-password不是非常REST’y.您可以将端点视为请求,然后将密码重置机制实际处理为身份提供者的一部分,而不是资源服务器(REST API).

然后,您可以在需要用户身份验证的每个OAuth2流中利用此身份提供程序会话.

选项B.1

当用户访问您的应用程序时,您使用prompt = none执行隐式授权身份验证请求(根据OpenID Connect规则).

如果此操作成功,则用户已在身份提供程序上进行了会话,您将获得一个令牌.当用户更改密码时,将创建此会话.

如果失败,则向用户显示当前登录界面并使用ROPC获取令牌.

选项B.2

您转储ROPC并开始使用隐式授权.这要求您将身份验证用户界面移出客户端应用程序并移入身份提供程序,然后需要处理基于重定向的流的细节,而不是ROPC更直接的请求/响应性质.

通过此设置,登录和密码重置操作将创建身份验证会话的概念,然后客户端应用程序可以利用该概念作为获取令牌的方式,而无需通过隐式授权来打扰用户.

最后的笔记

我个人认为拥有一个更加完善的身份提供者有一些优势;另外,对于如何在SPA中刷新令牌的问题,使用prompt = none支持的隐式授权似乎也是一个非常好的解决方案.

While SPAs cannot use refresh tokens, they can take advantage of other mechanics that provide the same function. A workaround to improve user experience is to use prompt=none when you invoke the /authorize endpoint. This will not display the login dialog or the consent dialog. In addition to that if you call /authorize from a hidden iframe and extract the new access token from the parent frame, then the user will not see the redirects happening.

(来源:Auth0 – Which OAuth 2.0 flow should I use?;重点是我的)

点赞