首页 文章

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

提问于
浏览
7

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

  • 我有自己的网站 .

  • 我有自己的API .

  • 我有自己的单页应用程序 .

  • 我有自己的用户数据库 .

The Goal :我需要通过提供用户名和密码来获取access_token .

我查看了OAuth2 Implicit Grant,但它要求用户在成功验证后批准/拒绝应用程序 . 它在我的情况下不起作用,因为我拥有应用程序和API .

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

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

这样做是否有 standard 方式?我目前的选择:

  • 忘记OAuth2并在用户POST用户名/密码时手动生成access_token(在这种情况下,当API上线时我必须引入OAuth2)

  • 使用OAuth2密码授予并在服务器上注入client_id / client_secret,这样只是为了保持客户端应用程序非常简单(同时避免所有这些dev / staging / prod client_id / client_secret对)

1 回答

  • 2

    隐式拨款

    你是对的,隐式授权类型看起来不合适 . 但我认为你不喜欢它的原因是不正确的,因为批准步骤不是强制性的,在Spring OAuth 2实现中(我不知道你正在使用哪个实现)你可以配置授权服务器自动批准授权请求,以便批准步骤被跳过 .

    我认为“隐含流动”不合适的原因是

    • 缺少通过提供客户端密钥和授权代码的客户端身份验证步骤 . 安全性降低 .

    • 访问令牌作为URL片段发送回(以便令牌不会转到服务器),这将继续保留在浏览器历史记录中

    • 如果发生XSS攻击,恶意脚本可以很好地将令牌发送到远程服务器

    资源所有者密码凭据授予

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

    如果客户端类型是机密或客户端已获得客户端凭据(或分配了其他身份验证要求),则客户端必须使用授权服务器进行身份验证,如第3.2.1节中所述 .

    这意味着此处不必强制使用客户端密钥进行客户端身份验证 . 现在,对于授权代码授权类型,我们需要客户端机密,因为用户直接向授权服务器提供他/她的凭证,然后当客户端请求访问令牌时,它没有除了客户端秘密之外的任何其他内容 . 向授权服务器证明这是一个真实的请求 .

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

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

    授权代码授权

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

    通过使用授权代码授予类型,您基本上可以使解决方案更加安全和通用 . 将来,如果要使用不同的SPA进行单点登录,则可以通过重用同一个授权服务器并将其与身份验证数据库(最好是LDAP服务器)集成来轻松完成 .

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

相关问题