什么是 OAuth?
从高层次开端,OAuth 不是API或服务:它是授权的开放标准,任何人都能够实施它。
更具体地说,OAuth 是运用程序能够用来为客户端运用程序供给“安全托付拜访”的标准。OAuth 经过 HTTPS 工作,并运用拜访令牌而不是凭证对设备、API、服务器和运用程序进行授权。
OAuth 有两个版别:OAuth 1.0a和OAuth 2.0。这些标准互相彻底不同,不能一同运用:它们之间没有向后兼容性。
哪一个更受欢迎?好问题! 现在,OAuth 2.0 是运用最广泛的 OAuth 方法。所以从现在开端,每当我说 “OAuth” 时,我都是在议论 OAuth 2.0——由于它很可能是您将要运用的。
为什么挑选 OAuth?
OAuth 是作为对直接身份验证形式的响应而创立的。这种形式因 HTTP 根本身份验证而出名,它会提示用户输入用户名和暗码。根本身份验证依然用作服务器端运用程序 API 身份验证的原始方法:用户发送 API 密钥 ID 和暗码,而不是在每次恳求时向服务器发送用户名和暗码。在 OAuth 出现之前,网站会提示您直接在表单中输入用户名和暗码,然后他们会以您的身份登录到您的数据(例如您的 Gmail 帐户)。这一般称为暗码反形式.
为了为网络创立更好的体系,为单点登录 (SSO) 创立了联合身份。在这种状况下,最终用户与其身份供给者攀谈,身份供给者生成一个加密签名的令牌,并将其交给运用程序以对用户进行身份验证。运用程序信赖身份供给者。只需该信赖关系适用于已签名的断语,您就能够开端了。下图显现了这是怎么工作的。
联合身份因 SAML 2.0 而出名,它是 2005 年 3 月 15 日发布的 OASIS 标准。这是一个很大的标准,但首要的两个组件是它的身份验证恳求协议(也称为 Web SSO)和它打包身份特点并对其进行签名的方法,称为SAML 断语。
SAML
SAML 根本上是您浏览器中的一个会话 cookie,可让您拜访网络运用程序。它在您可能期望在 Web 浏览器之外履行的设备配置文件类型和场景方面受到限制。
当 SAML 2.0 于 2005 年推出时,它是有道理的。然而,从那今后产生了许多改动。现在咱们具有现代网络和本机运用程序开发渠道。有单页运用程序 (SPA),例如 Gmail/Google Inbox、Facebook 和 Twitter。它们的行为与您的传统 Web 运用程序不同,由于它们对 API 进行 AJAX(后台 HTTP 调用)。手机也进行 API 调用,电视、游戏机和物联网设备也是如此。SAML SSO 在这方面并不是特别拿手。
OAuth 和 API
咱们构建 API 的方法也产生了很大改动。2005 年,人们出资于 WS-* 以构建 Web 服务。现在,大多数开发人员已转向 REST 和无状况 API。简而言之,REST 是经过网络推送 JSON 数据包的 HTTP 命令。
开发人员构建了许多 API。API 经济是您今天可能在董事会中听到的一个常见流行语。公司需求以答应许多设备拜访它们的方法维护它们的 REST API。在过去,你会输入你的用户名/暗码目录,运用程序会直接以你的身份登录。这就产生了托付授权问题。
“我怎样才能答应一个运用程序拜访我的数据而不用给它我的暗码?”
假如您曾经看过下面的对话框之一,那便是咱们正在议论的内容。这是一个询问是否能够代表您拜访数据的运用程序。
这是 OAuth。
OAuth 是 REST/API 的托付授权结构。它使运用程序能够在不走漏用户暗码的状况下取得对用户数据的有限拜访(规划)。它将身份验证与授权别离,并支撑处理不同设备功用的多个用例。它支撑服务器到服务器运用程序、根据浏览器的运用程序、移动/本机运用程序和控制台/电视。
您能够将其视为酒店钥匙卡,但用于运用程序。假如您有酒店钥匙卡,则能够进入您的房间。您怎么取得酒店钥匙卡?您有必要在前台进行身份验证才能取得它。认证并取得钥匙卡后,您能够拜访整个酒店的资源。
简单来说,OAuth 是:
- 运用恳求用户授权
- 用户授权App并提交证明
- 运用程序向服务器供给授权证明以获取令牌
- 令牌仅限于拜访用户为特定运用程序授权的内容
OAuth 中心组件
OAuth 建立在以下中心组件之上:
- Scopes and Consent (授权规划和用用户答应)
- Actors (用户)
- Clients (客户端)
- Tokens 认证票据
- Authorization Server (授权服务)
- Flows (授权进程)
OAuth Scope (OAuth 规划)
规划是您在运用程序恳求权限时在授权屏幕上看到的内容。它们是客户端在恳求令牌时要求的权限包。这些由运用程序开发人员在编写运用程序时编码。
规划将授权策略决议计划与履行别离。这是 OAuth 的第一个要害方面。权限是最重要的。它们并没有隐藏在您有必要进行逆向工程的运用程序层后边。它们一般列在 API 文档中:以下是此运用程序需求的规划。
OAuth 是一种互联网规划的处理计划,由于它针对每个运用程序。您一般能够登录到仪表板以检查您已颁发拜访权限的运用程序并吊销赞同。
OAuth 参与者
OAuth 流程中的参与者如下:
- 资源一切者:具有资源服务器中的数据。例如,我是我的 Facebook 个人资料的资源一切者。
- 资源服务器:存储运用程序想要拜访的数据的 API
- 客户端:想要拜访您的数据的运用程序
- Authorization Server : OAuth的首要引擎
资源一切者是一个能够随着不同凭证而改动的角色。它能够是最终用户,也能够是公司。
客户能够是揭露的和保密的。两者在 OAuth 命名法上有明显区别。能够信赖秘要客户端来存储隐秘。它们不在桌面上运转或经过运用程序商铺分发。人们无法对它们进行逆向工程并取得密钥。它们在最终用户无法拜访的受维护区域中运转。
公共客户端是浏览器、移动运用程序和物联网设备。
客户端注册也是 OAuth 的一个要害组成部分。这就像 OAuth 的 DMV。您需求为您的申请取得牌照。这便是您的运用程序徽标在授权对话框中的显现方法。
OAuth 令牌
拜访令牌是客户端用来拜访资源服务器 (API) 的令牌。他们注定是时间短的。以小时和分钟来考虑它们,而不是几天和一个月。您不需求秘要客户端来获取拜访令牌。您能够经过公共客户端获取拜访令牌。它们旨在针对互联网规划问题进行优化。由于这些令牌的寿命很短而且能够横向扩展,所以它们无法吊销,您只需等候它们超时即可。
另一个令牌是改写令牌。这要长得多;天,月,年。这可用于获取新令牌。要取得改写令牌,运用程序一般需求经过身份验证的秘要客户端。
改写令牌能够被吊销。在仪表板中吊销运用程序的拜访权限时,您正在停止其改写令牌。这使您能够强制客户端轮换秘要。您正在做的是运用改写令牌获取新的拜访令牌,而且拜访令牌经过网络拜访一切 API 资源。每次改写拜访令牌时,您都会取得一个新的加密签名令牌。密钥轮换内置于体系中。
OAuth 标准没有界说令牌是什么。它能够是您想要的任何格式。不过一般状况下,您期望这些令牌是 JSON Web 令牌(标准)。简而言之,JWT(发音为“jot”)是一种安全可靠的令牌认证标准。JWT 答应您运用签名对信息(称为声明)进行数字签名,并能够在今后运用隐秘签名密钥进行验证。要了解有关 JWT 的更多信息,请参阅A Beginner’s Guide to JWTs in Java。
令牌是从授权服务器上的端点检索的。两个首要端点是授权端点和令牌端点。它们针对不同的用例分隔。授权端点是您从用户那里取得赞同和授权的地方。这将回来一个授权颁发,表明用户已赞同它。然后将授权传递给令牌端点。令牌端点处理授权并说“很好,这是您的改写令牌和拜访令牌”。
您能够运用拜访令牌来拜访 API。一旦它过期,您将有必要运用改写令牌回来到令牌端点以获取新的拜访令牌。
缺点是这会引起许多开发人员的摩擦。OAuth 对开发人员来说最大的痛点之一是您有必要办理改写令牌。您将状况办理推给每个客户端开发人员。您取得了密钥轮换的好处,但您刚刚给开发人员带来了许多苦楚。这便是开发人员喜欢 API 密钥的原因。他们只需仿制/张贴它们,将它们放入文本文件中,然后就能够完结了。API 密钥对开发人员来说十分便利,但对安全性很不利。
这里有一个付费游戏问题。让开发人员履行 OAuth 流程能够提高安全性,但也会有更多的摩擦。东西包和渠道有时机简化工作并协助进行代币办理。走运的是,OAuth 现在现已相当老练,而且您最喜欢的语言或结构很可能有可用的东西来简化工作。
咱们现已评论了一些有关客户端类型、令牌类型和授权服务器的端点以及咱们怎么将其传递给资源服务器的内容。我提到了两种不同的流程:取得授权和取得令牌。这些不用在同一频道上产生。前端通道是经过浏览器的。浏览器将用户重定向到授权服务器,用户赞同。这产生在用户的浏览器上。一旦用户取得授权并将其交给运用程序,客户端运用程序就不再需求运用浏览器来完结 OAuth 流程来获取令牌。
令牌旨在由客户端运用程序运用,以便它能够代表您拜访资源。咱们称之为后台通道。反向通道是直接从客户端运用程序到资源服务器的 HTTP 调用,用于交流令牌的授权答应。这些通道用于不同的流,具体取决于您具有的设备功用。
例如,您经过用户代理授权的前端通道流可能如下所示:
- 资源一切者开端流程以托付对受维护资源的拜访
- 客户端经过浏览器重定向向授权服务器上的授权端点发送具有所需规划的授权恳求
- 授权服务器回来一个赞同对话框说“你答应这个运用程序拜访这些规划吗?” 当然,您需求对运用程序进行身份验证,因而假如您未对资源服务器进行身份验证,它会要求您登录。假如您现已有一个缓存的会话 cookie,您只会看到赞同对话框。检查赞同对话框并赞同。
- 授权颁发经过浏览器重定向传递回运用程序。这一切都产生在前声道。
此流程中还有一个变体,称为隐式流程。咱们会在一分钟内处理这个问题。
get https://accounts.google.com/o/oauth2/auth?scope=gmail.insert gmail.send
&redirect_uri=https://app.example.com/oauth2/callback
&response_type=code&client_id=812741506391
&state=af0ifjsldkj
这是一个带有一堆查询参数的 GET 恳求(出于示例目的未进行 URL 编码)。规划来自 Gmail 的 API。redirect_uri 是授权颁发应回来到的客户端运用程序的 URL。这应该与来自客户注册进程(在 DMV 处)的值相匹配。您不期望授权被退回到外国运用程序。响应类型因 OAuth 流而异。客户端 ID 也来自注册进程。State 是一个安全标志,类似于 XRSF。要了解有关 XRSF 的更多信息
HTTP/1.1 302 Found
Location: https://app.example.com/oauth2/callback?
code=MsCeLvIaQm6bTrgtp7&state=af0ifjsldkj
回来code
的是授权颁发,state
是为了保证它不是假造的,而且来自同一个恳求。
Front Channel 完结后,会产生 Back Channel Flow,将授权代码交流为拜访令牌。
客户端运用程序运用秘要客户端凭证和客户端 ID 向授权服务器上的令牌端点发送拜访令牌恳求。此进程将授权代码颁发交流拜访令牌和(可选)改写令牌。客户端运用拜访令牌拜访受维护的资源。
下面是它在原始 HTTP 中的样子:
Request
POST /oauth2/v3/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=MsCeLvIaQm6bTrgtp7&client_id=812741506391&client_secret={client_secret}&redirect_uri=https://app.example.com/oauth2/callback&grant_type=authorization_code
The grant_type is the extensibility part of OAuth. It’s an authorization code from a precomputed perspective. It opens up the flexibility to have different ways to describe these grants. This is the most common type of OAuth flow.
Response
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
}
响应是 JSON。您能够被迫或主动运用令牌。主动是在你的客户中有一个计时器。反应式是捕获错误并尝试获取新令牌。
取得拜访令牌后,您能够在身份验证标头中运用拜访令牌(运用作为token_type
前缀)来发出受维护的资源恳求。
curl -H "Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA" \
https://www.googleapis.com/gmail/v1/users/1444587525/messages
所以现在您有一个前台通道、一个后台通道、不同的端点和不同的客户端。您有必要针对不同的用例混合和匹配这些。这提高了 OAuth 的复杂性,而且会让人感到困惑。
OAuth 流程
第一个流便是咱们所说的隐式流。之所以称为隐式流,是由于一切通信都是经过浏览器进行的。没有后端服务器为拜访令牌兑换授权答应。SPA 是此流程用例的一个很好的示例。此流程也称为 2 Legged OAuth。
隐式流针对仅限浏览器的公共客户端进行了优化。拜访令牌直接从授权恳求回来(仅限前端通道)。它一般不支撑改写令牌。它假定资源一切者和公共客户端在同一台设备上。由于一切都产生在浏览器上,因而它最简单受到安全要挟。
黄金标准是 Authorization Code Flow,它同时运用前通道和后通道。这是咱们在本文中评论最多的内容。客户端运用程序运用前端通道流来获取授权码颁发。客户端运用程序运用反向通道将授权代码颁发交流拜访令牌(以及可选的改写令牌)。它假定资源一切者和客户端运用程序坐落不同的设备上。这是最安全的流程,由于您能够对客户端进行身份验证以兑换授权颁发,而且令牌永远不会经过用户代理传递。不仅有隐式和授权代码流程,您还能够运用 OAuth 履行其他流程。相同,OAuth 更像是一个结构。
关于服务器到服务器的场景,您可能期望运用Client Credential Flow。在这种状况下,客户端运用程序是一个秘要客户端,它独立运转,不代表用户。它更像是一种服务帐户类型的场景。您只需求客户的凭证即可完结整个流程。这是一个反向通道,仅用于运用客户端的凭证获取拜访令牌。它支撑同享隐秘或断语作为运用对称或非对称密钥签名的客户端凭证。
对称密钥算法是一种加密算法,只需您有暗码,就能够解密任何内容。在维护 PDF 或 .zip 文件时经常会发现这种状况。
公钥暗码术或非对称暗码术是运用成对密钥的任何暗码体系:公钥和私钥。公钥任何人都能够读取,私钥对一切者来说是崇高的。这答应数据安全而无需同享暗码。
还有一种称为Resource Owner Password Flow 的留传形式。这与运用用户名和暗码的直接身份验证计划十分类似,因而不引荐运用。它是本地用户名/暗码运用程序(例如桌面运用程序)的传统授权类型。在此流程中,您向客户端运用程序发送用户名和暗码,然后它从授权服务器回来拜访令牌。它一般不支撑改写令牌,而且假定资源一切者和公共客户端在同一台设备上。当您有一个只想运用 OAuth 的 API,但您有老派的客户要处理时。
OAuth 最近增加的是Assertion Flow,它类似于客户端凭证流。增加此内容是为了翻开联邦的主意。此流程答应授权服务器信赖来自第三方(例如 SAML IdP)的授权颁发。授权服务器信赖身份供给者。该断语用于从令牌端点获取拜访令牌。这关于出资 SAML 或 SAML 相关技术并答应他们与 OAuth 集成的公司来说十分有用。由于 SAML 断语是时间短的,所以此流程中没有改写令牌,您有必要在每次断语过期时继续检索拜访令牌。
不在 OAuth 标准中,是Device Flow。没有网络浏览器,只有电视之类的控制器。用户代码是从授权恳求回来的,有必要经过拜访带有浏览器的设备上的 URL 来兑换授权。客户端运用程序运用反向通道流来轮询拜访令牌和可选的改写令牌的授权批准。也很受 CLI 客户端的欢迎。
咱们现已介绍了运用不同参与者和令牌类型的六种不同流程。它们是必要的,由于客户的才能,咱们需求怎么取得客户的赞同,谁正在赞同,这给 OAuth 增加了许多复杂性。
当人们问您是否支撑 OAuth 时,您有必要澄清他们的要求。他们是在问您是否支撑一切六个流程,仍是只支撑首要流程?一切不同的流程之间都有许多可用的粒度。
安全与企业
OAuth 的运用规划很广。运用隐式流,有许多重定向和许多错误空间。有许多人企图在运用程序之间利用 OAuth,假如您不遵循引荐的 Web Security 101 指南,这很简单做到。例如:
- 始终将 CSRF 令牌与
state
参数一同运用以保证流完整性 - 始终将重定向 URI 列入白名单以保证正确的 URI 验证
- 运用客户端 ID 将同一客户端绑定到授权颁发和令牌恳求
- 关于秘要客户,保证客户秘要不被走漏。不要将客户端秘要放入经过 App Store 分发的运用程序中!
一般来说,对 OAuth 最大的抱怨来自于安全人员。它与 Bearer 令牌有关,它们能够像会话 cookie 相同传递。您能够传递它,一切顺利,它不会以加密方法绑定到用户。运用 JWT 很有协助,由于它们无法被篡改。可是,最终,JWT 只是一串字符,因而能够轻松仿制它们并在标头中运用Authorization
。
OpenID Connect
为了处理伪身份验证问题,结合了 OAuth 2.0、Facebook Connect 和 SAML 2.0 的最佳部分来创立OpenID Connect。id_token
OpenID Connect (OIDC) 运用新的客户端签名和UserInfo
获取用户特点的端点扩展 OAuth 2.0。与 SAML 不同,OIDC 供给了一组标准的身份规划和声明。示例包括:profile
、email
、address
和phone
。
OIDC 的创立是为了经过使事物彻底动态化来实现 Internet 可扩展性。不再需求像 SAML 那样下载元数据和联合。有用于动态联合的内置注册、发现和元数据。您能够输入您的电子邮件地址,然后它会动态发现您的 OIDC 供给商,动态下载元数据,动态知道它将运用什么证书,并答应 BYOI(自带身份)。它支撑企业的高保证等级和要害 SAML 用例。
OIDC 因谷歌和微软而出名,这两家公司都是前期采用者。
Request
GET https://accounts.google.com/o/oauth2/auth?
scope= openid email &
redirect_uri=https://app.example.com/oauth2/callback&
response_type=code&
client_id=812741506391&
state=af0ifjsldkj
Response
HTTP/1.1 302 Found
Location: https://app.example.com/oauth2/callback?
code=MsCeLvIaQm6bTrgtp7&state=af0ifjsldkj
令牌响应的授权颁发包括一个 ID 令牌。
Request:
POST /oauth2/v3/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=MsCeLvIaQm6bTrgtp7&client_id=812741506391&
client_secret={client_secret}&
redirect_uri=https://app.example.com/oauth2/callback&
grant_type=authorization_code
Response:
{
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ..."
}
您能够看到它在 OAuth 之上很好地分层,以将 ID 令牌作为结构化令牌回来。ID 令牌是 JSON Web 令牌 (JWT)。JWT(又叫“jot”)比根据 XML 的巨大 SAML 断语小得多,能够在不同设备之间高效传递。JWT 包括三个部分:标头、正文和签名。标头说明运用什么算法对其进行签名,声明在正文中,并在签名中签名。
Open ID Connect 流程触及以下步骤:
- 发现 OIDC 元数据
- 履行 OAuth 流程以获取 ID 令牌和拜访令牌
- 获取 JWT 签名密钥并可挑选动态注册客户端运用程序
- 根据内置日期和签名在本地验证 JWT ID 令牌
- 根据需求运用拜访令牌获取其他用户特点
OAuth 2.0 总结
OAuth 2.0 是一种用于托付拜访 API 的授权结构。它触及恳求资源一切者授权/赞同的规划的客户端。授权颁发交流拜访令牌和改写令牌(取决于流程)。有多个流程能够处理不同的客户端和授权场景。JWT 可用于授权服务器和资源服务器之间的结构化令牌。
OAuth 具有十分大的安全表面积。保证运用安全东西包并验证一切输入!
OAuth 不是身份验证协议。OpenID Connect 为身份验证计划扩展了 OAuth 2.0,一般称为“带大括号的 SAML”。