I don't know if I just have some kind of blind spot or what, but I've read the OAuth 2 spec many times over and perused the mailing list archives, and I have yet to find a good explanation of why the Implicit Grant flow for obtaining access tokens has been developed. Compared to the Authorization Code Grant, it seems to just give up on client authentication for no very compelling reason. How is this "optimized for clients implemented in a browser using a scripting language" (to quote the specification)?

这两个流程的起点是相同的(来源:https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-22):

客户端通过将资源所有者的用户代理定向到授权端点来启动流。 授权服务器对资源所有者进行身份验证(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。 假设资源所有者授予访问权限,授权服务器使用前面提供的重定向URI(在请求中或在客户端注册期间)将用户代理重定向回客户端。

重定向URI包括一个授权代码(授权代码流) 重定向URI在URI片段中包含访问令牌(隐式流)

这里是流分裂的地方。在这两种情况下,此时重定向URI指向客户端托管的某个端点:

In the Authorization code flow, when the user agent hits that endpoint with the Authorization code in the URI, code at that endpoint exchanges the authorization code along with its client credentials for an access token which it can then use as needed. It could, for example, write it into a web page that a script on the page could access. The Implicit flow skips this client authentication step altogether and just loads up a web page with client script. There's a cute trick here with the URL fragment that keeps the access token from being passed around too much, but the end result is essentially the same: the client-hosted site serves up a page with some script in it that can grab the access token.

因此我的问题是:跳过客户端身份验证步骤可以获得什么?


当前回答

我刚刚看到一些关于OAuth 2.0的文章。作者指出隐式流背后的原因是JS应用程序在那里的请求非常有限:

如果您想知道为什么隐式类型包含在OAuth 2.0中,那么 解释很简单:同源策略。那时,正面 应用程序不允许向不同的主机发送请求 使用代码获取访问令牌。今天我们有CORS (Cross-Origin) 资源共享)。

https://medium.com/securing/what-is-going-on-with-oauth-2-0-and-why-you-should-not-use-it-for-authentication-5f47597b2611

其他回答

在隐式流程中,如果用户的浏览器被损坏(邪恶的扩展/病毒),那么损坏就可以访问用户的资源,并可以做坏事。

在认证流中,腐败不能,因为它不知道客户端的秘密。

通常的解释是,当您使用JavaScript客户端时,隐式授权更容易实现。但我认为这种看法是错误的。如果您使用的JavaScript客户端直接通过XMLHttpRequest请求受保护的资源,隐式授权是您唯一的选择,尽管它不太安全

授权码授权提供了额外的安全性,但它仅在web服务器请求受保护资源时才有效。由于web服务器可以存储访问令牌,因此访问令牌暴露在Internet上的风险较小,并且可以发出持续较长时间的令牌。由于web服务器是受信任的,所以可以给它一个“刷新令牌”,所以当旧的访问令牌过期时,它可以获得一个新的访问令牌。

But -- and this is a point that's easy to miss -- the security of the Authorization code flow works only if the web server is protected with a session, which is established with user authentication (login). Without a session, an untrusted user could just make requests to the web server, using the client_id, and it would be the same as if the user had the access token. Adding a session means that only an authenticated user can access the protected resources. The client_id is just the "identity" of the JS webapp, not authentication of said webapp.

这还意味着您可以在OAuth令牌过期之前结束会话。没有使访问令牌失效的标准方法。但是如果你的会话过期了,访问令牌就没用了,因为除了web服务器没有人知道它。如果一个不受信任的用户获得了对会话密钥的访问权,那么他们只能在会话有效期间访问受保护的资源。

如果没有网络服务器,你必须使用隐式授权。但这意味着访问令牌暴露在Internet上。如果一个不受信任的用户获得了它的访问权限,他们可以使用它直到过期。这意味着他们将拥有比授权代码授予更长的访问时间。因此,您可能需要考虑让令牌提前过期,并避免授予对更敏感资源的访问权。

*EDIT: More recently, people are recommending that you avoid using the Implicit grant, even on web apps without a server. Instead you can use the Authorization Code grant configured with an empty secret, along with PKCE. The auth-code grant avoids storing the access token in your browser history, and PKCE avoids exposing it if someone hijacks the redirect URL to steal the auth code. In this case you would need the server to avoid returning a refresh token, since your client probably can't store it securely. And it should issue an access token with the same limitations mentioned above.

https://www.rfc-editor.org/rfc/rfc6749#page-8

Implicit The implicit grant is a simplified authorization code flow optimized for clients implemented in a browser using a scripting language such as JavaScript. In the implicit flow, instead of issuing the client an authorization code, the client is issued an access token directly (as the result of the resource owner authorization). The grant type is implicit, as no intermediate credentials (such as an authorization code) are issued (and later used to obtain an access token). When issuing an access token during the implicit grant flow, the authorization server does not authenticate the client. In some cases, the client identity can be verified via the redirection URI used to deliver the access token to the client. The access token may be exposed to the resource owner or other applications with access to the resource owner's user-agent. Implicit grants improve the responsiveness and efficiency of some clients (such as a client implemented as an in-browser application), since it reduces the number of round trips required to obtain an access token.

隐式授权允许使用GET从授权端点获取令牌。这意味着授权服务器不必支持CORS。

如果这不是一个问题,并且没有其他与授权服务器不灵活相关的问题(例如,出于某种原因,刷新令牌不是可选的),那么授权代码流是首选的,即使是对于公共客户端,根据最近的行业趋势和至少这个(当前)官方草案实例。

从历史上看,实现隐式流还有其他原因,但目前似乎它们被授权代码授予提供的安全优势所超越,包括:

为机密客户端通过反向通道交付和使用令牌的选项 没有在公共客户端的浏览器历史中公开令牌 在发布令牌之前中断未经授权的流-使用PKCE,用于“各种OAuth客户端”

除了其他答案,还必须认识到,隐式配置文件只允许一个前端通道流,而不是需要回调授权服务器的授权代码流;这在OpenID Connect(一种建立在Auth 2.0之上的SSO协议)中非常明显,其中隐式流类似于非常流行的SAML POST绑定,而授权代码流类似于不太广泛部署的SAML Artifact绑定