如何使用oAuth2对SPA用户进行身份验证?

时间:2017-01-06 00:10:58

标签: api authentication oauth oauth-2.0 single-page-application

好吧,我花了几天时间寻找一个合适的解决方案,以便在使用SPA时如何正确地验证用户身份。

  1. 我有自己的网站。
  2. 我有自己的API。
  3. 我有自己的单页应用程序。
  4. 我有自己的用户数据库。
  5. 目标我需要通过提供用户名和密码来获取access_token。

    我查看了OAuth2隐式授权,但它要求用户在成功验证后批准/拒绝应用。由于我同时拥有应用程序和API,因此它不适用于我的情况。

    我查看了OAuth2密码授予,这是不完美的,因为我需要公开client_id / client_secret。

    我正在考虑OAuth2的原因是因为API最终会公开。

    是否有标准这样的方式?我目前的选择:

    1. 忘记OAuth2并在用户POST用户名/密码时手动生成access_token(在这种情况下,我必须在API公开时引入OAuth2)
    2. 使用OAuth2密码授予并在服务器上注入client_id / client_secret,这样只是为了保持客户端应用程序非常简单(同时避免所有这些dev / staging / prod client_id / client_secret对)

1 个答案:

答案 0 :(得分:2)

隐性授予

您认为隐式授予类型看起来不合适是正确的。但是我认为您不赞成这样做的原因是不正确的,因为批准步骤不是强制性的,并且在Spring OAuth 2实现中(我不知道您使用的是哪种实现),您可以将授权服务器配置为自动批准授权请求,以便跳过批准步骤。

我认为“隐式流程”不合适的原因是

  1. 缺少提供客户端密码和授权代码的客户端身份验证步骤。因此安全性降低。
  2. 访问令牌作为URL片段发送回(以便令牌不会发送到服务器),它将继续保留在浏览器历史记录中
  3. 如果发生XSS攻击,则恶意脚本可以很好地将令牌发送到远程服务器

资源所有者密码凭据授予

如果授权服务器和资源服务器相同,我认为这是一种快速启动和运行的方法。第4.3.2节中的RFC 6749说:

  

如果客户端类型为机密或向客户端颁发了客户端凭据(或分配了其他身份验证要求),则客户端必须按照第3.2.1节中的说明,通过授权服务器进行身份验证。

这意味着此处没有强制使用客户端密码进行客户端身份验证。现在,对于授权码授予类型,我们需要客户机密,因为用户直接将其凭据提供给授权服务器,然后当客户请求访问令牌时,除了客户机密之外,它没有其他任何东西可用于向授权服务器证明这是真实请求。

但是,在资源所有者密码凭证授予类型的情况下,用户已将其凭证提供给客户端本身,然后客户端将发送这些相同的用户凭证以请求访问令牌。因此,访问令牌请求只能使用用户凭据进行身份验证,如果我们在此处不提供客户机密,那么我认为我们在安全性方面不会丢失任何东西。

因此,您绝对可以在SPA中使用密码凭据授予类型。

授权码授予

我认为这应该是首选选项,前提是客户端机密未存储在浏览器中。在进行用户身份验证(以及可选的用户批准)之后,授权服务器可以使用URL中的授权代码将浏览器重定向到服务器端端点。服务器端端点将使用授权码,客户端ID和客户端机密(仅存储在服务器端)请求访问令牌。一旦访问令牌可用,服务器端端点就可以将用户重定向(HTTP响应代码302)到带有CSRF保护和访问令牌的适当cookie的SPA URL。因此,我们不会在浏览器中存储客户端密码。

通过使用授权码授予类型,基本上可以使该解决方案更加安全和通用。将来,如果您想使用其他SPA进行单点登录,则可以通过重新使用与授权数据库集成的同一授权服务器(最好是LDAP服务器)来轻松实现此目的。

有关更多详细信息,请参阅我的StackOverflow answer here