为什么会有“授权码"?“隐式"时在 OAuth2 中流动流量这么好用? [英] Why is there an "Authorization Code" flow in OAuth2 when "Implicit" flow works so well?

查看:24
本文介绍了为什么会有“授权码"?“隐式"时在 OAuth2 中流动流量这么好用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用隐式"流程,在资源所有者(即用户)授予访问权限后,客户端(可能是浏览器)将获得访问令牌.

With the "Implicit" flow the client (likely a browser) will get a access token, after the Resource Owner (i.e. the user) gave access.

然而,使用授权码"流程,客户端(通常是 Web 服务器)只会在资源所有者(即用户)授予访问权限后才获得授权码.使用该授权代码,客户端然后再次调用 API,传递 client_id 和 client_secret 以及授权代码以获取访问令牌.此处描述得很好.

With the "Authorization Code" flow however, the client (usually a web server) does only get an authorization code after the Resource Owner (i.e. the user) gave access. With that authorization code the client then makes another call to the API passing client_id and client_secret together with the authorization code to obtain the access token. All well described here.

两个流程都具有完全相同的结果:访问令牌.但是,隐式"流程要简单得多.

Both flows have the exact same result: an access token. However, the "Implicit" flow is much simpler.

问题:当隐式"流接缝没问题时,为什么还要麻烦授权码"流?为什么不对网络服务器使用隐式"?

提供方和客户都需要做更多的工作.

It's more work both for the provider and the client.

推荐答案

tl;dr:这都是出于安全原因.

OAuth 2.0 希望满足这两个标准:

OAuth 2.0 wanted to meet these two criteria:

  1. 您希望允许开发人员使用非 HTTPS 重定向 URI,因为并非所有开发人员都有启用 SSL 的服务器,如果他们这样做了,也并非总是正确配置(非自签名、受信任的 SSL 证书、同步服务器时钟...).
  2. 您不希望黑客能够通过拦截请求来窃取访问/刷新令牌.

详情如下:

由于安全原因,隐式流只能在浏览器环境中使用:

The implicit flow is only possible in a browser environment because of security reasons:

隐式流程中,访问令牌直接作为散列片段(而不是作为 URL 参数)传递.关于散列片段的一件重要事情是,一旦您点击包含散列片段的链接,只有浏览器知道散列片段.浏览器会将哈希片段直接传递到目标网页(重定向 URI/客户端的网页).哈希片段具有以下属性:

In the implicit flow the access token is passed directly as a hash fragment (not as a URL parameter). One important thing about hash fragment is that, once you follow a link containing a hash fragment, only the browser is aware of the hash fragment. Browsers will pass the hash fragment directly to the destination webpage (the redirect URI / the client's webpage). Hash fragment have the following properties:

  • 它们不是 HTTP 请求的一部分,因此它们不能被服务器读取,因此它们不能被中间服务器/路由器拦截(这很重要).
  • 它们仅存在于浏览器 - 客户端 - 因此读取哈希片段的唯一方法是使用在页面上运行的 JavaScript.

这使得可以将访问令牌直接传递给客户端,而没有被中间服务器拦截的风险.这有一个警告,即只能是可能的客户端,并且需要运行客户端的 javascript 才能使用访问令牌.

This makes it possible to pass an Access Token directly to the client without the risk of it being intercepted by an intermediary server. This has the caveat of only being possible client side and needs javascript running client side to use the access token.

隐式流也有安全问题,需要进一步的逻辑来解决/避免例如:

The implicit flow also has security issues that requires further logic to workaround/avoid for instance:

  • 攻击者可以从不同网站/应用程序的用户那里获取访​​问令牌(假设他是另一个网站/应用程序的所有者),在他们的网站上记录令牌,然后将其作为 URL 参数传递在您的网站上因此冒充您网站上的用户.为避免这种情况,您需要检查与访问令牌关联的客户端 ID(例如,对于 Google,您可以使用 tokeninfo 端点)以确保令牌是使用您自己的客户端 ID(即由您自己的应用程序)颁发的或检查签名如果您使用的是 IDToken(但这需要您的客户端密码).
  • 如果身份验证请求不是来自您自己的财产(称为会话固定攻击),为避免这种情况,您需要从您的网站生成一个随机散列,将其保存在 cookie 中并在状态中传递相同的散列身份验证请求的 URL 参数,当用户回来时,您使用 cookie 检查状态参数,它必须匹配.

授权代码流中,不能直接在 URL 参数中传递访问令牌,因为 URL 参数是 HTTP 请求的一部分,因此您的请求将通过的任何中间服务器/路由器如果您不使用加密连接 (HTTPS) 允许所谓的中间人攻击,pass(可能是数百个)可以读取访问令牌.

In the authorization code flow it is not possible to pass an access token directly in a URL parameter because URL parameters are part of the HTTP Request, therefore any intermediary server/routers by which your request would pass (could be hundreds) could be able to read the access token if you are not using en encrypted connection (HTTPS) allowing what's known as Man-in-the-middle attacks.

理论上可以直接在 URL 参数中传递访问令牌,但身份验证服务器必须确保重定向 URI 使用带有 TLS 加密的 HTTPS 和受信任的"SSL 证书(通常来自证书颁发机构)不是免费的)以确保目标服务器是合法的并且 HTTP 请求是完全加密的.让所有开发人员购买 SSL 证书并在他们的域上正确配置 SSL 将是一个巨大的痛苦,并且会极大地减慢采用速度.这就是为什么提供一个中间人一次性授权码",只有合法的接收者才能交换(因为你需要客户端机密),并且该代码对于潜在的黑客拦截未加密交易的请求毫无用处(因为他们不知道客户端的秘密).

Passing the access token directly in a URL param could in theory be possible but the auth sever would have to make sure the redirect URI is using HTTPS with TLS encryption and a 'trusted' SSL certificate (typically from a Certificate Authority that is not free) to be sure that the destination server is legitimate and that the HTTP request is fully encrypted. Having all developers purchase an SSL certificate and properly configure SSL on their domain would be a huge pain and would slow adoption down tremendously. This is why an intermediary one-time-use "authorization code" is provided that only the legitimate receiver will be able to exchange (because you need the client secret) and that the code will be useless to potential hackers intercepting the requests over unencrypted transactions (because they don't know the client secret).

您也可以争辩说,隐式流不太安全,存在潜在的攻击媒介,例如在重定向时欺骗域 - 例如通过劫持客户端网站的 IP 地址.这就是为什么隐式流只授予访问令牌(应该具有有限的使用时间)而从不刷新令牌(时间不受限制)的原因之一.为了解决这个问题,我建议您尽可能在支持 HTTPS 的服务器上托管您的网页.

You could also argue that the implicit flow is less secure, there are potential attack vectors like spoofing the domain upon redirect - for example by hijacking the IP address of the client's website. This is one of the reasons why the implicit flow only grants access tokens (which are supposed to have a limited time use) and never refresh tokens (which are unlimited in time). To remedy this issue, I advise you to host your webpages on an HTTPS-enabled server whenever possible.

这篇关于为什么会有“授权码"?“隐式"时在 OAuth2 中流动流量这么好用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆