为什么在“隐式”stream程运行良好时,OAuth2中存在“授权码”stream?

在“隐式”stream程中,客户端(可能是浏览器)将在资源所有者(即用户)授予访问权限后获得访问令牌。

然而,使用“授权码”stream程,客户端(通常是Web服务器)在资源所有者(即用户)授予访问权限后才获得授权码。 使用该授权码,客户端再次调用API以传递client_id和client_secret以及授权码以获得访问令牌。 这里都有很好的描述 。

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

问题: 为什么要打扰“授权码”stream程,当“隐式”stream程接缝良好? 为什么不使用“隐式”的networking服务器?

这对提供者和客户来说都是更多的工作。

博士:这全是因为安全原因。

OAuth 2.0想要符合这两个标准:

  1. 您希望允许开发人员使用非HTTPSredirectURI,因为并非所有开发人员都具有启用了SSL的服务器,并且如果他们这样做,并不总是正确configuration(非自签名,可信SSL证书,同步服务器时钟…)。
  2. 您不希望黑客通过拦截请求来窃取访问/刷新令牌。

详情如下:

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

隐式stream中 ,访问令牌直接作为散列片段(而不是URL参数)传递。 哈希片段的一个重要的事情是,一旦你跟随一个包含哈希片段的链接,只有浏览器知道哈希片段。 浏览器将散列片段直接传递到目标网页(redirectURI /客户端的网页)。 散列片段具有以下属性:

  • 它们不是HTTP请求的一部分,因此它们不能被服务器读取,因为它们不能被中间服务器/路由器拦截(这很重要)。
  • 它们只存在于浏览器 – 客户端 – 所以读取散列碎片的唯一方法是使用运行在页面上的JavaScript。

这样就可以将访问令牌直接传递给客户端,而不会被中间服务器拦截。 这只是可能的客户端的需要,需要运行客户端的JavaScript来使用访问令牌。

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

直接在URL参数中传递访问令牌在理论上是可能的,但是authentication服务器将不得不确保redirectURI使用带有TLSencryption的HTTPS和“可信”SSL证书(通常来自不是免费的证书颁发机构)确保目标服务器是合法的,并且HTTP请求已完全encryption。 让所有开发人员购买SSL证书并在其域中正确configurationSSL将是一个巨大的痛苦,并会大大降低采用率。 这就是为什么提供中间一次性使用的“授权码”,只有合法的接收者才能交换(因为你需要客户端的密码),而且代码对于潜在的黑客截获未encryption事务的请求将是无用的(因为他们不知道客户的秘密)。

你也可以争辩说,隐式stream是不太安全的,有潜在的攻击媒介,如redirect欺骗域 – 例如劫持客户端的网站的IP地址。 这就是为什么隐式stream只授予访问令牌(应该有有限的时间使用)并且永远不刷新令牌(这是无限的时间)的原因之一。 为了解决这个问题,我build议您尽可能将网页托pipe在支持HTTPS的服务器上。

隐式stream程使得整个stream程非常容易,但也不太安全
由于客户端应用程序(通常是在浏览器中运行的JavaScript)不太受信任,因此不会返回用于长期访问的刷新令牌。
您应该将此stream程用于需要临时访问(几个小时)用户数据的应用程序。
将访问令牌返回给JavaScript客户端也意味着基于浏览器的应用程序需要格外小心 – 考虑可能会将访问令牌泄露给其他系统的XSS攻击。

https://labs.hybris.com/2012/06/05/oauth2-the-implicit-flow-aka-as-the-client-side-flow