基于OAuth2.0的第三方认证

时间:2022-02-03 17:33:18

浅显易懂的解释

来源

yahoo OAuth认证

原理

理解OAuth 2.0:原理、分类

一张图搞定OAuth2.0:是什么,怎么用

应用自身,完成用户认证:

  缺点:

  1.不同的访问Web应用提供不同的用户凭证,对用户来说不方便

  2.Web提供者,花费大量时间、精力、资源开发自己的认证系统。尤其每个子系统需要独立认证

值得信任的第三方能够提供一种免费的认证服务。

  提供者均为值得信赖的IT服务提供商,比如微软、Google、Facebook、Twitter,以及国内的新浪、腾讯、网易、人人和豆瓣等。就目前来说,这些第三方认证服务绝大部分均是基于OAuth 2.0设计的。

  OAuth的目的却是定义一种协议帮助资源的拥有者在不提供自身凭证的前提下授权第三方应用以他的名义存取受保护的资源。OAuth的全称为“Open Authorization”,所以它是一个开放的协议,目前最新的版本为2.0。

角色:

  资源拥有者(RO:Resource Owner):资源的拥有者也是授权者,如果它是一个“人”,一般就是指最终用户。由于“资源”在这个场景中表示为用户的电子邮箱地址,所以资源拥有者自然就是指最终用户。

  客户端应用(Client):需要取得资源拥有者授权并最终访问受保护资源的应用,对于我们的场景来说,就是我们创建的App。

  资源服务器(Resource Server):最终承载资源的服务器,它一般体现为一个可被调用的Web API。对于我们提供的场景来说,客户端通过调用新浪微博得Web API获得用户的电子邮箱地址,所以新浪微博就是资源服务器。

  授权服务器(Authorization Server):它对用户(一般情况下为资源拥有者)和客户端应用实施认证,并在用户授权的情况下向客户端应用颁发Access Token。在我们提供的场景中,资源服务器和认证服务器合二为一,均为新浪微博。

客户端凭证:

  需要针对某种类型的第三方认证服务来开发我们自己的应用,我们需要向采用的认证服务提供商对该应用进行注册,注册成功之后会得到一个唯一标识该应用的ClientID和对应的ClientSecret(ClientID/ClientSecret是Windows Live Connect 的说法,Twitter和Facebook分别叫做ConsumerKey/ComsumerSecret和AppID/AppSecret。如果采用Google提供的OAuth 2.0 API,ClientID和ClientSecret是不需要的。)。它们相当于客户端应用的凭证,认证服务利用它们来确定其真实身份。

  Windows Live Connect API的应用注册一个ClientID。

处理流程:

  基于OAuth2.0的第三方认证

  首先得取得资源拥有者的授权,所以第一轮消息交换旨在让客户端获得资源拥有者(即用户)的授权。客户端应用得到授权之后会得到一个被称为Authorization Grant的对象,该对象实际上就是一个简单的字符串用以表示成功取得了用户的授权。

  接下来客户端应用利用此Authorization Grant向授权服务取获取用于访问受保护资源所需的Access Token。

  在成功获得Access Token之后,客户端应用将其附加到针对资源服务器的请求中以获取它所需要的目标资源。

Authorization Grant:

  代表一种中间凭证(Intermediate Credential),它代表了资源拥有者针对客户端应用获取目标资源的授权。

  Implicit:它代表一种“隐式”授权方式,即客户端在取得资源拥有者(最终用户)授权的情况下直接获取Access Token,而不是间接地利用获取的Authorization Grant来取得Access Token。换句话说,此种类型的Authorization Grant代表根本不需要Authorization Grant,那么上面介绍的“Three-Legged OAuth”变成了“Two-Legged OAuth”。

  Authorization Code:这是最为典型的Authorization Grant,客户端应用在取得资源拥有者授权之后会从授权服务器得到一个Authorization Code作为Authorization Grant。在它获取寄宿于资源服务器中的目标资源之前,需要利用此Authorization Code从授权服务器获取Access Token。

  Resource Owner Password Credentials:资源拥有者的凭证直接作为获取Access Token的Authorization Grant。这种Authorization Grant类型貌似与OAuth设计的初衷向违背(OAuth的主要目的在于让客户端应用在不需要提供资源拥有者凭证的情况下能够以他的名义获取受保护的资源),但是如果客户端程序是值得被信任的,用户(资源拥有者)向其提供自己的凭证也是可以接受的。

  Client Credentials:客户端应用自身的凭证直接作为它用于获取Access Token的Authorization Grant。这种类型的Authorization Grant适用于客户端应用获取属于自己的资源,换句话说客户端应用本身相当于资源的拥有者。

  

Implicit Authorization Grant授权流程:

  基于OAuth2.0的第三方认证

  用户会先被客户端应用重定向到授权服务器(login.live.com),具体的地址为“https://login.live.com/oauth20_authorize.srf”。

    response_type: 表示请求希望获取的对象类型,在此我们希望获取的是Access Token,所以这里指定的值为“token”。

    redirect_uri: 表示授权服务器在获得用户授权并完成对用户的认证之后重定向的地址,Access Token就以Hash(#)的方式附加在该URL后面。客户端应用利用这个地址接收Access Token。

    client_id: 唯一标识被授权客户端应用的ClientID。

    scope: 表示授权的范围,如果采用“wl.signin”意味着允许用户从客户端应用直接登录到Live Services,如果Scope为“wl.basic”则表示运行客户端应用获取联系人信息。如果读者朋友希望了解Windows Live Connect具体支持那些Scope,可以查阅Windows Live Connect API的官方文档。

  授权服务器在获取用户的授权之后,会生成一个Access Token。

    会提取请求中指定的重定向地址(即redirect_uri参数),然后将生成的Access Token以Hash(#)的形式附加在该地址后面,最终针对这个携带有Access Token的新地址返回一个重定向的响应。

    重定向地址对应着客户端应用需要获取授权资源的页面,该页面可以直接从代表当前地址的URL中获得Access Token,并利用它来获取目标资源。对于我们的例子来说,它需要获取当前Windows Live帐号的基本信息,请求的地址为“https://apis.live.net/v5.0/me”,Access Token以查询字符串的形式(“?access_token={accesstoken}”)提供给资源服务器,后者据此验证请求的合法性并在验证成功的情况下将当前用户的基本信息以JSON的形式返回给客户端应用。

  Authorization Grant存在这样的两个问题:

    其一,授权服务器没有对客户端应用进行认证,因为获取Access Token的请求只提供了客户端应用的ClientID而没有提供其ClientSecret;

    其二,Access Token是授权服务器单独颁发给客户端应用的,照理说对于其他人(包括拥有被访问资源的授权者)应该是不可见的。

Authorization Code Authorization Grant:

  最为典型的Authorization Grant,它“完美”地实现了指定的OAuth初衷:资源拥有者可以在向客户端应用提供自身凭证的前提下授权它获取受保护的资源。

  基于OAuth2.0的第三方认证

  Authorization Code类型的Authorization Grant具有完整的“三段式”授权流程

  Implicit类型的Authorization Grant授权的客户端运行于存客户端(浏览器)上下文环境,

  Authorization Code类型的Authorization Grant则适用于运行于服务器的应用,比如ASP.NET MVC应用的Controller,或者是定义在View中的服务端程序。

  客户端应用需要首先取得Authorization Code,因为它代表了资源拥有者对它的授权,并且是获取Access Token时必须提供的凭证。

    首先向授权服务器发送一个获取Authorization Code的请求,请求的地址同样为“https://login.live.com/oauth20_authorize.srf”,相应的参数同样以查询字符串的形式提供。与Implicit类型Authorization Grant获取Access Token的请求一样,此时需要提供如下4个完全一样的参数。

    如果当前用户尚未登录但Windows Live Services,他会被自动重定向到登录页面。在尚未对客户端应用进行授权的情况下,如左图所示的授权页面会显示出来。

   基于OAuth2.0的第三方认证

    在取得登录用户的授权之后,授权服务器会返回一个重定向的响应,而请求提供的redirect_uri参数值直接作为重定向地址。由授权服务器生成的Authorization Code就以查询字符串(?code={authorizationcode})的方式附加在重定向URL的后面。

    重定向的请求被客户端应用接收后,Authorization Code被提取并保存起来。

    接下来客户端应用会利用得到的Authorization Code向授权服务器获取Access Token,这一般为HTTP-POST请求。作为请求消息主体传递的内容除了作为参数“code”的Authorization Code之外,还包含如下一些必需的参数。

      client_id: 唯一标识被授权客户端应用的ClientID。

      client_secret:唯一标识被授权客户端应用的ClientSecret

      redirect_uri:之前获取Authorization Code时指定的重定向地址。

      grant_type:采用的Authorization Grant类型,参数值为“ authorization_code”。

    授权服务器接受到请求之后,除了利用提供的ClientID和ClientSecrete对客户端应用实施验证之外,还会检验之前获取Authorization Code提供的ClientID和重定向地址是否与本次提供的一致。成功完成检验之后,授权服务器会生成一个Access Token作为响应内容发送给客户端应用。整个响应内容除了Access Token之外,还可以获取其他一些相关的信息,比如Access Token的类型(token_type)、过期时间(“expires_in”,单位为秒)、授权范围(“scope”,与获取Authorization Code时指定的一致)以及表示认证身份的安全令牌(“authentication_token”)。

    客户端应用接受到响应之后从中提取出Access Token。当它试图获取受保护资源的时候,将此Access Token附加到请求上,便会以授权用户的名义得到它所需要的资源。

  安全问题的解决:

    虽然客户端获取Authorization Code时不需要指定ClientSecret,但是在获取Access Token时ClientRecret则是必需的,授权服务器只有在成功验证客户端应用身份的情况下才会颁发Access Token;

    针对Access Token的消息交换仅限于授权服务器和客户端应用之间进行,所以第三方(包括 当前用户)都无法获取到正确的Access Token。

  

refresh token:

  处于安全性考虑,Access Token并非终身有效,而是具有一个过期时间。上面我们给出了授权服务器返回Access Token的响应内容,其“expires_in”属性表示的就是Access Token的有效期限。那么,Access Token过期之后该如何处理呢?是否需要重新获得Authorization Code并利用它得到新的Access Token呢?

  得到Authorization Code之后,可以在利用它获取Access Token的时候,让授权服务器一并返回一个叫做Refresh Token的令牌。与Access Token不同,Refresh Token是一个长期有效的安全令牌,当Access Token过期之后,我们可以利用它获取一个新的Access Token。

  对于Windows Live Connection来说,如果希望在获取Access Token的时候让授权服务器返回一个Refresh Token,其指定的授权范围必须具有一个名为“wl.offline_access”的Scope,它表示允许客户端程序在任何时候(包括用户尚未登录Windows Live Connect的情况下)读取和更新用户信息。对于具有如此授权范围的Access Token请求,授权服务器返回的响应中会按照如下的形式包含Refresh Code的内容。

  在客户端应用从响应内容成功提取出Refresh Token之后,可以在任何时候向授权服务器(地址依然是“https://login.live.com/oauth20_authorize.srf”)发送获取新的Access Token的请求。和直通过Authorization Code获取Access Token一样,这通常也是一个HTTP-POST请求

    grant_type:采用的Authorization Grant类型,这里自然就是“ refresh_code”。

  授权服务器对请求作必要验证后,会将新的Access Token置于响应的主体内容返回给客户端应用。完整地响应内容如下所示,我们不难看出:其中不仅仅包含新的Access Token,还返回了一个新的Refresh Token。

采用Authorization Code类型的Authorization Grant,客户端应用直接在Web服务器与授权服务器进行消息交换