你知道OAuth2是什么吗?看看简单到复杂的客户端

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lowpeys5166/article/details/88641974

第三方应用程序在无法取得用户名称、密码的情况下,想对社交网站请求使用者私人资源,现今最常见的方案是采用OAuth2,而作为OAuth2客户端,只要遵守社交网站规范的流程就可以了。若进一步想了解授权服务器、资源服务器的具体实作,此时,我们该怎么面对一大堆的观念、术语,以及参数呢?

从基本身份验证到客户端凭证

OAuth2授权的框架,主要规范于RFC6749。从核心概念来看,对于客户端(Client)与资源拥有者(Resource Owner)之间授权的流程,会独立出来──由授权服务器(Authorization Server)核发存取令牌(Access Token)给客户端,而客户端向资源拥有者提出请求时,必须出示存取令牌,接着,资源拥有者可以透过令牌来取得相关授权信息,然后,再决定是否允许客户端存取受保护的资源(Protected Resources)。虽然,资源服务器最终都是看存取令牌做事,不过,该如何核发令牌?OAuth2有许多角色定义(方才只提到部份),并依它们之间的互动方式,规范出四种授权类型流程(Grant Type Flow),其中涉及了大量参数,然而,初次接触OAuth2的开发者,经常又从授权码(Authorization Code)的类型开始认识,这时,大家应该都曾有瞬间坠入五里雾的感觉。

在采用OAuth2的场合之前,更简单的作法,其实是运用基本(Basic)验证的场合,像是有个服务器,必须具有凭证才能存取,基于名称、密码的基本身份验证就够用了。不过,如果有多台服务器都有限制存取的需求,每台服务器都须执行名称、密码验证,就会显得麻烦了,这时,就可考虑OAuth2的客户端凭证(Client Credentials)核发流程。而在OAuth2当中,使用者(User)与客户端是分离的两个概念。使用者通常是个拥有账户的人,客户端是指某个应用程序(前端网页、App、服务器等),在OAuth2客户端凭证中,基本上,没有使用者参与,而且,通常也不会有Role-based访问控制中的角色概念,取而代之的是范畴(scope)──客户端会被授予范畴,类似Role-based访问控制中,使用者会被授予角色。

OAuth2客户端凭证就像是基本身份验证的延伸,每台要限制存取的服务器上,会设定哪些资源只允许具有某些范畴的客户端存取。而这类似于Role-based得访问控制中,某些资源只允许具有某些角色的使用者存取,客户端必须提供存取令牌,服务器依令牌取得范围(scope)信息,从而决定是否可以存取资源。因为OAuth2客户端凭证没有使用者参与,适用于内部服务器之间的资源存取,对授权服务器请求存取令牌时,必须提供客户端ID与密钥(Secret)──前者像是社交网站上要接API时的应用程序名称,后者就像是应用程序密钥了。

 

拥有用户时的密码凭证

当授权过程涉及使用者,有些资源会基于使用者、角色来进行访问控制,OAuth2提供了密码凭证(Password Credentials)核发类型,某些程度上,也是最简单、容易理解的类型,因为就像是传统验证授权的延伸,使用者在客户端输入名称、密码,客户端对授权服务器请求核发存取令牌,在资源服务器上,就可依令牌取得用户的角色等信息,决定是否符合某资源的角色设定。除了用户名称、密码之外,密码凭证核发的类型在请求核发存取令牌时,也必须同时提供客户端ID与密钥,授权服务器会依此决定客户端被授予的范畴,因此除了依角色来限制资源存取之外,运用OAuth2密码凭证时,还可以为不同客户端设定各自的资源权限。运用密码凭证核发流程的情境,通常是客户端与服务属于同一个单位,该单位本身就拥有用户的帐户信息,由于服务服务器只要认同存取令牌就可以存取,也能用来实现 Single Sign-On,也就是一次登入,就可使用各个独立服务的功能。在采用密码凭证核发类型时,授权服务器可以决定是否同时核发更新令牌(Refresh Token)──其有效期比存取令牌来得长,可在存取令牌过期之后,无需用户提供名称、密码下,直接透过更新令牌来取得新的存取令牌,因此可用来实作自动登入之类的功能。

 

适用第三方应用的隐含与授权码

如果我手中拥有资源、用户帐户,第三方应用程序想要存取用户私有的资源,我不能私下给第三方应用程序用户名称、密码,用户也不会给这些敏感信息,怎么办呢?这时,可以采用隐含(Implicit)或授权码授权类型,因为在不提供用户名称、密码下,又要能授予权限,因此流程上就繁复许多。采取隐含与授权码类型时,第三方应用程序必须能在我这边设定应用程序名称、密钥,以及重导(Redirect)网址,客户端必须能听从重导指示(通常是个浏览器),还会有个第三方应用服务器。而第三方应用服务器,会附上redirect-uri参数(值必须与应用程序设定的重导网址相同),将客户端重导至授权服务器,等到用户在输入名称、密码后,确认授予第三方应用程序的范畴,接下来的流程,则依隐含与授权码而不同。

在隐含授权类型时,授权服务器直接核发存取令牌,并重导至redirect-uri指定的位置,此时,所进行的形式,会像是下列这样:https://3rdsvr/app.html#access_token=84f9-749e-45db&token_type=bearer&expires_in=43199&scope=message,其中的#分段,包含了存取令牌相关信息,而浏览器不会发送#分段后的信息,因此,在app.html之中,必须有JavaScript,以便提取#分段中的存取令牌,再用令牌向资源服务器进行请求。因此,隐含授权是针对只能在前端(浏览器)执行的应用程序,虽然,OAuth2的规范要求核发流程必须在加密联机中进行,然而存取令牌就直接附在重导网址上头,依然是有安全上的疑虑,这可以采取授权码流程来避免。授权码流程在重导浏览器时,会附上的是授权码(而不是存取令牌),形式会像是https://3rdsvr/app?code=61vXSV,第三方应用程序服务器取得code请求参数后,在后端对授权服务器请求存取令牌,整个过程中,浏览器不会接触到存取令牌,从而避免了存取令牌曝露在前端的问题。内文来源至:sbf999捕游戏集合 http://www.indoorair.org.tw/

 

依需求而迭加的概念

若一开始接从OAuth2的授权码类型开始了解,就会骤然面临大量术语,像是:第三方、客户端、密钥(往往与用户名称、密码混淆)、资源拥有者、范畴(往往与角色混淆)、重导等,实际上,这些术语观念,是从简单的需求到复杂的考虑,而逐一迭加上去的。开发者可以从简单的客户端凭证开始,逐一认识更繁复的授权类型。这么一来,除了不用突然面对大量术语之外,我们也可以明确地知道:哪些术语是前一个观念的延伸,哪些设定又会是基于前一个授权类型的设定而来;之后在真正实作时,也能明确地知道,哪个授权类型,才是真正符合实际的授权需求。

猜你喜欢

转载自blog.csdn.net/lowpeys5166/article/details/88641974