好吧,我已经花了几天时间来寻找一个合适的解决方案,如何正确地验证用户时,与SPA。
1.我有自己的网站。
1.我有自己的API。
1.我有自己的单页应用程序。
1.我有自己的用户数据库。
目标:* 我需要通过提供用户名和密码来获取access_token。*
我看过OAuth2隐式授权,但它要求用户在成功认证后批准/拒绝应用程序。它在我的情况下不起作用,因为我同时拥有应用程序和API。
我查看了OAuth2密码授予,它并不完美,因为我需要公开client_id/client_secret。
我之所以关注OAuth2,是因为API最终将是公共的。
是否有标准的方法来执行此操作?我当前的选项:
1.忘记OAuth2,在用户发布用户名/密码时手动生成access_token(在这种情况下,我必须在API公开时引入OAuth2)
1.使用OAuth2密码授予并在服务器上注入client_id/client_secret,以便保持客户端应用程序非常简单(还要避免所有这些dev/staging/prod client_id/client_secret对)
2条答案
按热度按时间pes8fvy91#
隐式授权
隐式授权类型看起来不合适是对的,但是我认为你不喜欢它的理由是不正确的,因为批准步骤不是强制性的,在Spring OAuth 2实现中(我不知道你使用的是哪个实现),你可以配置授权服务器自动批准授权请求,这样就跳过了批准步骤。
我认为“内隐流”不适用的原因是
1.缺少提供客户端密码和授权码的客户端身份验证步骤,因此安全性较低。
1.访问令牌作为URL片段发回(这样令牌就不会返回到服务器),它将继续保留在浏览器历史记录中
1.如果发生XSS攻击,恶意脚本很可能将令牌发送到远程服务器
资源所有者密码凭据授予
如果授权服务器和资源服务器是相同的,我认为这是一个快速启动和运行的方法。RFC 6749在4.3.2节中说:
如果客户端类型是机密的或客户端被授予了客户端凭证(或被分配了其他认证要求),则客户端必须按照第3.2.1节所述向授权服务器进行认证。
这意味着使用客户端秘密的客户端认证在这里不是强制的。现在,对于授权码授予类型,我们需要客户端秘密,因为用户直接向授权服务器提供他/她的凭证,然后当客户端请求访问令牌时,它不提供;除了客户端秘密之外,我们没有任何其他东西来向授权服务器证明这是真实的请求。
但在资源所有者密码凭据授予类型的情况下,用户已将其凭据提供给客户端本身,然后客户端将发送这些相同的用户凭据来请求访问令牌。因此,访问令牌请求可以只使用用户凭据进行身份验证,如果我们在此处不提供客户端密码,我不认为我们会在安全性方面失去任何东西。
因此,您完全可以在SPA中使用密码凭据授予类型。
授权码授予
我认为这应该是首选选项,前提是客户端密码不存储在浏览器中。(以及可选的用户批准),授权服务器可以利用URL中的授权码将浏览器重定向到服务器侧端点。服务器侧端点将使用授权码来请求访问令牌,客户端ID和客户端密码(其仅存储在服务器侧)。一旦访问令牌可用,服务器侧端点可以重定向(HTTP响应代码302)用户使用用于CSRF保护和访问令牌的适当cookie访问SPA URL。因此,我们不会将客户端机密存储在浏览器中。
通过使用授权码授予类型,您基本上使解决方案更加安全和通用。将来,如果您想使用不同的SPA执行单点登录,您可以通过重用同一个授权服务器及其与验证数据库的集成(最好是LDAP服务器)轻松地完成。
有关详细信息,请参阅我的StackOverflow answer here。
eufgjt7s2#
在前面已经说过的基础上,我建议使用“授权代码授予”,但要添加PKCE(代码交换证明密钥/“像素”)扩展--以增加安全性,无论您是实现“公共”还是“机密”类型的客户端。
使用PKCE,您不需要为公共客户端提供客户端密钥(/这有点像在每次身份验证尝试/示例的最开始/开始时生成临时客户端密钥-尽管即使使用PKCE为机密客户端提供客户端密钥,理想情况下您仍然应该使用客户端密钥)。