美文网首页
OAuth 授权介绍

OAuth 授权介绍

作者: Miss_Ella | 来源:发表于2020-09-19 20:19 被阅读0次

    如今网络应用,手机app越来越多,每个app都需要一个账号,对于个人来说就变得繁琐,需要记住都账号密码很多。 为了解决这些问题以及安全问题,各种登录方式陆续诞生.

    OAuth 登录

    OAuth是open authentication的缩写,OAuth并不是API或服务:它是一种开放的授权标准,任何人都可以实现。OAuth是用来为第三方应用提供“secure delegated access”的一个标准。OAuth通过https和访问令牌对设备,api和服务器进行认证,而不需要用户名密码。OAuth有1.0和2.0两个版本,他们之间完全不同,不能一起使用, 两个版本之间也不兼容。目前OAuth 2.0使用比较广泛,这里主要介绍2.0版本。

    为什么要用Oauth

    OAuth是相对直接身份验证模式而创建的。直接身份验证模式通过HTTP进行验证,提示用户输入用户名和密码。基本身份验证仍然是服务器端应用程序API身份验证的原始形式:然而用户发送的是API key ID和 secret 进行验证而不是发送用户名和密码。在使用OAuth之前,网站会提示在网页中输入用户名和密码,并且会以你的身份登录你的数据(例如您的Gmail帐户)。这通常称为密码反模式。

    为了创建更好的web系统,单点登录(SSO)经常被使用。SSO登录涉及到联合身份的创建。在这种情况下,最终应用程序与身份提供者(authorize endpoint)进行对话,并且身份提供者生成一个加密签名的令牌(token),并将其交给应用程序以验证用户身份。如果签名能够被验证,应用程序就会信任身份提供者,验证流程如下:

    image.png

    OAuth API

    我们构建API的方式也发生了很多变化。 在2005年,人们研究用WS- *来构建Web服务。 现在,大多数开发人员已转向REST和无状态API。 简而言之,REST是HTTP命令通过网络推送JSON数据包。

    开发人员构建了大量的API。 现在可能会在会议室听到“ API economy”这个常见词。 公司需要保护REST API, 同时允许许多设备访问它们。 过去,只要需要输入用户名/密码,应用程序将直接以你的身份登录。 这引起了委托授权问题。
    “如何允许应用访问我的数据而不必输入密码?”
    以下 是一个应用程序,询问它是否可以代表你访问数据。


    image.png

    这是OAuth。

    OAuth是REST / API的委托授权框架。 它使应用程序无需提供用户密码即可获得对用户数据的有限访问权限(scopes)。 它使身份验证与授权脱钩,并支持解决不同设备功能的多个用例。 它支持服务器到服务器应用程序,基于浏览器的应用程序,移动/本地应用程序以及控制台/电视。
    你可以认为这是(对于应用程序)酒店房卡。 如果你有酒店房卡,则可以进入你的房间。 如何获得酒店钥匙卡? 你必须在前台通过身份验证才能获取它。 认证并获得房卡后,您可以访问整个房间的资源。

    简单来说,OAuth的就是:

    1. 应用程式要求使用者授权
    2. 用户授权应用并提供证明
    3. 应用程序向服务器提供了获得令牌(token)的授权证明
    4. 令牌(token)仅限于访问用户为特定应用授权的内容

    OAuth 组件

    • Scopes and Consent
    • Actors
    • Clients
    • Tokens
    • Authorization Server
    • Flows

    OAuth Scopes

    Scopes是我们在应用程序请求权限时在授权屏幕上看到的内容。 它们是客户在请求令牌时要求的权限束(bundles of permissions)。 这些由应用程序开发人员在编写应用程序时进行编码。


    image.png

    Scopes使授权策略决策与执行脱钩。 这是OAuth的第一个关键方面。 权限位于前面和中间。 它们没有隐藏在你必须进行反向工程的应用层的后面。 它们通常列在API文档中:这是此应用程序要求的范围。
    我们必须获用户的同意。 这称为首次使用信任。 网络上的用户体验发生了重大变化。 OAuth之前的大多数人都只是用用户名和密码对话框。 这是网络上的一个新概念,如今已成为流行趋势。 现在,你必须授权并征得同意。
    同意(consent)可能会因申请而异。 它可能是时间敏感的范围(天,周,月),但是并非所有平台都允许你选择持续时间。 当你同意时要注意该应用程序可以代表你执行一些操作-例如 LinkedIn向网络中的每个人发送垃圾邮件。
    OAuth是基于Internet的解决方案,因为它针对每个应用程序。 您通常可以登录到信息中心,以查看你有权访问的应用程序并撤消同意。

    OAuth Actors

    OAuth流程中的actors如下:

    • 资源所有者(Resource Owner):拥有资源服务器中的数据。 例如,我是我的Facebook个人资料的资源所有者。
    • 资源服务器(Resource Server):用于存储应用程序要访问的数据的API
    • 客户端(Client):想要访问你的数据的应用程序
    • 授权服务器(Authorization Server):OAuth的主要引擎
    image.png

    资源所有者有不同的角色:它可以是最终用户,但也可以是公司。
    客户端可以是公开或者保密的。 在OAuth中,两者之间有很大的区别。 机密客户端可以用来来存储机密。 它们不在台式机上运行或不在应用商店中分发。 人们无法对其进行反向工程并获得密钥。 它们在受保护的区域内运行,终端用户无法访问它们。
    公共客户端是浏览器,移动应用程序和IoT设备。


    image.png

    客户端注册也是OAuth的关键组成部分, 就像OAuth的DMV。你需要为应用获取license, 这是您的应用徽标在授权对话框中显示的方式。

    OAuth Tokens

    访问令牌(access token)是客户端用来访问资源服务器(API)的令牌。 它们生命走起是短暂的,通常是几分钟或者几小时,而不是几天或者一个月。 我们通过公共客户端就可以获取访问令牌。 它们旨在优化互联网规模问题。 由于这些令牌的寿命很短且可以扩展,因此无法撤消,只需要等待它们超时即可。

    另一个令牌是刷新令牌(refresh token), 他们寿命很长,通常是几天,几个月或者几年, 可以用他们来获取新令牌。 为了获得刷新令牌,应用程序通常需要通过具有身份验证的机密客户端。
    刷新令牌可以被撤消。 在控制台中撤消应用程序的访问权限时,就是杀死其刷新令牌。 这使你能够强制客户端旋转秘钥, 使用刷新令牌来获取新的访问令牌,而访问令牌正在通过网络访问所有API资源。 每次刷新访问令牌时,都会得到一个新的加密签名的令牌。 密钥旋转内置于系统中。
    OAuth规范没有定义令牌是什么。 它可以是你想要的任何格式。 但是通常这些令牌为JSON Web Token(标准)。 简而言之,JWT是令牌认证的安全且值得信赖的标准。 JWT允许使用签名对信息(称为声明)进行数字签名,并可以在以后使用秘密签名密钥进行验证。
    令牌是从从授权服务器上获取的,两个主要端点是授权端点(authorize endpoint)和令牌端点(token endpoint.)。 根据不同的使用情况将它们分开, 授权端点是获得用户同意和授权的地方,他们将返回表明用户已同意的认证授权(authorization grant), 然后将授权传递到令牌端点,令牌端点处理授权,并说“好,这是你的刷新令牌和访问令牌”。


    image.png

    可以使用访问令牌来访问API。 过期后,必须使用刷新令牌返回令牌端点,以获取新的访问令牌。
    对于开发人员来说,OAuth的最大痛苦之一就是必须管理刷新令牌。你将状态管理推给每个客户端开发人员,你可以获得密钥轮换的好处,但给开发人员带来了很多痛苦。这就是开发人员喜欢API密钥的原因。他们可以只复制/粘贴它们, API密钥对开发人员来说非常方便,但对安全性却很不利。
    还有收费问题,让开发人员执行OAuth流程可以提高安全性,但是会遇到更多麻烦。工具箱和平台有机会简化工作并帮助令牌管理。幸运的是,OAuth现在已经很成熟了,你最喜欢的语言或框架很可能具有可用来简化事情的工具。
    我们已经讨论了客户端类型,令牌类型和授权服务器的端点,以及如何将其传递给资源服务器。提到了两种不同的流程:获得授权和获得令牌。这些不必发生在同一频道上。前通道(front channel)是浏览器中经过的通道,浏览器将用户重定向到授权服务器,用户表示同意,这是在用户的浏览器上发生的。一旦用户获得了授权授权并将其交给应用程序,客户端应用程序就不再需要使用浏览器来完成OAuth流以获取令牌。
    令牌应由客户端应用程序使用,以便它可以代表你访问资源。 我们称其为后通道(back channel)。 后通道是直接从客户端应用程序到资源服务器的HTTP调用,以交换令牌的认证授权。 这些通道用于不同的流程,具体取决于你拥有的设备功能。


    image.png

    例如,您通过用户代理授权的前端渠道流可能如下所示:

    1. 资源所有者开始流程以委派对受保护资源的访问
    2. 客户端通过浏览器重定向到授权服务器上的授权端点发送具有所需作用域的授权请求
    3. Authorization Server返回一个同意对话框,说“您是否允许该应用程序访问这些作用域?” 当然,您需要对应用程序进行身份验证,因此,如果您未对资源服务器进行身份验证,它将要求您登录。 如果您已经有一个缓存的会话Cookie,则只会看到“同意”对话框。 查看同意对话框,并同意。
    4. 授权授予通过浏览器重定向传递回应用程序。 这一切都发生在前通道上。


      image.png

    该流中也有一个变化,称为隐式流。
    Request:

    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编码)。 scope来自Gmail的API。 redirect_uri是授权授权应返回到的客户端应用程序的URL。 这应该与客户端注册过程中的值(在DMV上)匹配。 response_type会改变OAuth流。clieny ID是注册获取的。 state是一个安全标志,类似于XRSF。

    Response

    HTTP/1.1 302 Found
    Location: https://app.example.com/oauth2/callback?
    code=MsCeLvIaQm6bTrgtp7&state=af0ifjsldkj
    

    返回的code是authorization grant,state是为了确保它不是伪造的,并且来自同一请求。完成前通道后,后通道流就会开始,将交换授权码来获取访问令牌。

    客户端应用程序使用机密的客户端credentials和 client ID将访问令牌请求发送到授权服务器上的令牌端点(token endpoint)。 此过程发送授权代码以获取访问令牌和(可选)刷新令牌。 客户端使用访问令牌访问受保护的资源。


    image.png

    以下是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
    

    grant_type是OAuth的可扩展部分,这是授权代码。 它很灵活,使他们可以采用不同的方式来描述这些grant。 这是OAuth流的最常见类型。

    Reponse

    {
      "access_token": "2YotnFZFEjr1zCsicMWpAA",
      "token_type": "Bearer",
      "expires_in": 3600,
      "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
    }
    

    Reponse为JSON。两种方式使用令牌: 1.在客户端中设置一个计时器。2.捕获错误并尝试获取新令牌。
    获得访问令牌后,可以在Authentication Header中使用访问令牌(使用token_type作为前缀)来发出受保护的资源请求。

    curl -H "Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA" \
      https://www.googleapis.com/gmail/v1/users/1444587525/messages
    

    前通道,后通道,不同的端点和不同的客户端。 我们必须针对不同的场景将它们混合使用和匹配。 这样会提高Oauth的复杂度

    OAuth flow

    1. 第一种flow就是所谓的隐式flow。之所以称为隐式flow(Implicit Flow.),是因为所有通信都是通过浏览器进行的。没有后端服务器为访问令牌兑换授权。 SPA是该流程用例的一个很好的例子。此flow也称为2 Legged OAuth。
      隐式flow仅仅针对浏览器的公共客户端进行了优化。访问令牌直接从授权请求中返回(仅前通道),它通常不支持刷新令牌。假定资源所有者和公共客户端在同一设备上。由于一切都发生在浏览器上,因此它最容易受到安全威胁的攻击。

    2. 黄金标准是使用前通道和后通道的授权码流(Authorization Code Flow),也称为3 Legged。这就是我们在本文中讨论最多的内容。客户端应用程序使用前通道流来获取授权码授予。客户端应用程序使用后向通道将授权代码授权交换为访问令牌(以及可选的刷新令牌)。假定资源所有者和客户端应用程序位于单独的设备上。这是最安全的流程,因为您可以对客户端进行身份验证以兑换授权,并且令牌永远不会通过用户代理传递。不仅有隐式和授权码流,您还可以使用OAuth进行其他处理。同样,OAuth更像是一个框架。

    3. 对于服务器到服务器的方案,您可能要使用客户端凭据流(Client Credential Flow)。在这种情况下,客户端应用程序是一个机密的客户端,它以自己身份访问而不是代表用户。这更多是服务帐户类型的情况。您只需要客户的凭据即可完成整个流程。这是只需要back channel的flow, 通过client 凭据就能获取访问令牌。它支持共享密钥或断言作为使用对称或非对称密钥签名的客户端凭据。
      对称密钥算法是加密算法,只要有密码,就可以解密任何内容。在保护PDF或.zip文件时通常会发现这种情况。
      公钥密码学或非对称密码学是使用密钥对的密码系统:公钥和私钥。任何人都可以读取公共密钥,并用公钥加密,所有者可以使用私有密钥解密。这样既保证了数据安全也无需共享秘钥。

    4. 还有一种称为资源所有者密码流(Resource Owner Password Flow)的旧模式。这与使用用户名和密码的直接身份验证非常相似,因此不建议使用。这是本机用户名/密码应用程序(例如桌面应用程序)的旧式授权类型。在此流程中,您向客户端应用程序发送用户名和密码,并从授权服务器返回访问令牌。它通常不支持刷新令牌,并且假定资源所有者和公共客户端在同一设备上。当API 只支持OAuth,但又有老派客户需要处理时可以使用。

    5. OAuth的最新流是断言流(Assertion Flow),它类似于客户端凭据流(Client Credential Flow)。添加它是为了打开联盟的想法。此流程允许授权服务器信任来自第三方(例如SAML IdP)的授权。授权服务器信任身份提供者。该断言用于从令牌端点获取访问令牌。这对于投资于SAML或SAML相关技术并允许其与OAuth集成的公司来说非常有用。由于SAML断言是短暂的,因此此流程中没有刷新令牌,并且每次断言到期时都必须继续检索访问令牌。

    6. 设备流( Device Flow)不是OAuth规范中的内容。没有网络浏览器,只有电视之类的控制器。用户代码从授权请求中返回,必须通过使用浏览器访问设备上的URL进行授权才能兑现。客户端应用程序使用反向通道流来轮询访问令牌和可选的刷新令牌的授权批准。也受CLI客户端欢迎。

    我们使用了不同的参与者和令牌类型,涵盖了六种不同的流程。由于客户的能力,我们需要如何获得客户的同意,进行同意的方式,所以它们是必需的,这给OAuth增加了很多复杂性。
    当人们问您是否支持OAuth时,您必须明确他们的要求。他们是在问您是否支持所有六个流程,还是仅支持主要流程?所有不同的流程之间都有很多可用的粒度。

    相关文章

      网友评论

          本文标题:OAuth 授权介绍

          本文链接:https://www.haomeiwen.com/subject/ricaektx.html