`
djb4ke
  • 浏览: 55124 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

OAuth in OpenSocial-第二篇:2-legged OAuth

阅读更多

OpenSocial and 2-legged OAuth 基本概念
Two legs的意思是OAuth的参与者为两个:Social Network Server和App server.

2-legged OAuth协议是两个服务器backend的交互,与3-legged相比,缺少了user这个角色,不需要经过user-agent(Gadget,浏览器等)。

因为不需要user,所以自然不需要用户认证。这就要求用户事先已经允许App Server访问存放于Social Site的私人数据。

 

因为我还没能跑出实际例子,所以自己直观的感觉较少,主要是通过阅读一些文章了解。

 

 

 

以下主要是翻译自一篇介绍2-legged的文章,其中也加了不少自己的补充:

原文地址:http://sites.google.com/site/oauthgoog/2leggedoauth/2opensocialrestapi&ei=ISHpS8ijB4qOkQX-xoSICw&usg=AFQjCNH_6WhDOc9Vbgx7k1p3DsDk5F17ug&sig2=3-QKOl13GUAHFnTHEWKe0g  (需over the wall)

 

OpenSocial的REST API是通过OAuth协议实现授权机制:
简单描述一下就是,OpenSocial中定义了REST API,通过call这些API可以访问私人数据,当取涉及隐私的数据时,需要对的app进行授权,而OAuth是基于API的授权协议,显然再合适不过。但是对于一些公共数据,则不需要授权。

 

OAuth在OpenSocial中有两种形式,2-legged 和 3legged。
本文将解释这两种形式不同的应用场景,以及为何对于大多数OpenSocial container(比如Igoogle等能放置gadget的容器),2-legged OAuth变得更加重要并首先被支持。

 



 

首先学习一下OpenSocial Restful API的Spec第四节:

http://www.opensocial.org/Technical-Resources/opensocial-spec-v08/restful-api-specification

 

Request Authentication and Authorization Context
Each RESTful operation has a request context that usually includes authentication and authorization information. Typically, the context information includes the requestor id (the user initiating the request) and app ID (the application, or whatever is acting as the user's agent). It may include other container-specific information.

Containers MUST be an OAuth Core 1.0 Service Provider (a web application that allows access via OAuth). Containers MAY also support other ways to establish a request context. Containers MUST also support the Consumer Request OAuth extension, in which the end user has not directly authorized the operation. Applications SHOULD ensure that the users have given prior consent, implicitly or explicitly, to the operation or class of operations. However, containers MAY require an additional prior trust relationship be established by the app in order to allow use of Consumer Request OAuth.

If a Consumer has a user identifier and wishes to indicate that the operation is being done on behalf of that particular user, it SHOULD provide the OAuth extension parameter xoauth_requestor_id with the OAuth signed parameters. Consumers SHOULD only provide this if the user has given prior consent, implicitly or explicitly, to the operation or class of operations, as it indicates that the operation is being done on behalf of the user. Container SPs MUST either honor the parameter or ignore it as if it were not provided.

Thus, a request context usually includes the requesting application (the OAuth Consumer), and may include the requesting user, either implicitly via an oauth_token or explicitly via xoauth_requestor_id. It may also include additional information via extensions or other channels (cookies, URI parameters, client SSL certificates, etc.) A container may also accept requests with no authentication or authorization (authnz) information at all for public data. A container may provide a public version (e.g., of a profile) if no authnz information is provided.

Note that the data provided for a given RESTful URI MAY vary per requestor or app. Thus, the meaning of the resource at a given URI is "the view of the information available to the current requestor/app combination". In the case where no information is available due to lack of authorization, an HTTP 401 Unauthorized response SHOULD be returned to the client. In the case where at least some view of the information is available, it SHOULD be returned using a 200 status, with a standard OAuth WWW-Authenticate: header indicating that additional information may be available when using a different authnz context.

  

大致意思就是每个RESTcall都拥有自己的请求上下文,一般情况下,这个上下文包含了授权和认证信息。比如包括了请求者的Id(在初始化request时产生),以及app ID(call Rest api的主动方的id)

Gadget容器必须是OAuth的Service Provider(SP)

Gadget容器必须也支持Consumer Request OAuth extension协议:http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/1/spec.html,通过此协议,用户无需做身份认证操作(2-legged实现的基础)。Consumer Request OAuth extension协议实现的功能就是无需用户操作的在consumer和SP间通过OAuth的签名流程对request进行签名。

app使用前需要已经被用户授权,容器需要与app建立信任关系(其过程就是在容器中保存app的secret和key)。

容器还应该支持无需验证授权获取公共数据的接口。



 

 

2-legged 与 3-legged的区别及联系

OAuth一般是指3-legged OAuth,这点从OAuth协议就能看出,整个OAuth的过程需要用户的这个角色,用户需要登录(身份认证)和允许APP访问数据(授权操作)。因此3 legged OAuth是OAuth的标准版本,并已被Yahoo Google Aol等部署应用,3-legged需要用户的参与,从OAuth consmer开始,重定向到OAuth provider,去做登录及授权,如果授权通过,用户又被弹回OAuth consumer,因此用户这一些列操作被戏称为“dance”。而这支非常灵动的舞蹈,让整个网络的app和数据互动起来了,但是代价却是让用户头晕的一些列操作,用户体验是非常差的= =#(可以想想,一个并不了解OAuth流程的用户,对于两个site间来回跳并且要阅读很多类似法律条款的授权警告,以及操作,是多么的困惑)

 

之前我写过一篇介绍flicker作为sp,Ning作为Consumer的case study。

http://djb4ke.iteye.com/blog/664065
flicker增加用户体验的方式是只需授权一次,而后授权信息一直保留并可管理。

 

 

我还看过一些SNS网站做联系人导入的做法,也是为了增加用户体验,具体做法是:
要求用户提供第三方网站的用户名和密码!!

比如renren,人人还在下面有个注释“人人网不会记录你的密码,请放心使用”

不做太多评论,只想说一句“如果每个服务商都承诺对用户的用户名密码完全无视,还要OAuth干啥?”
至于renren取联系人是通过OAuth,app验证通过后取联系人信息,还是renren拿着用户名密码到你邮箱里扫视一遍,顺便拿个联系人信息,就不得而知了。
(警告:互联网由于技术不断发展确实是变得越来越安全,但是同时,在我们不断信任各种服务商的同时,警惕性决不能下降,试想一下跑到一个陌生的站点,很可能是个山寨站点,同样要求你提供你的邮箱密码,同样承诺无视你的密码,后果会如何= =)

 

2-legged OAuth是标准OAuth的变种形式,不需要前面提到的“dance”,即不需要用户参与。
2-legged OAuth又被称作Signed Fetch or Phone Home,尤其在OpenSocial社区
Signed Fetch比较好理解,就是获取数据的操作是签过名的,这里签名是指参照OAuth签名流程的签名,签完名自然就代表此请求是加上identity了。
如今,广泛使用中的大部分REST API调用是通过2-legged OAuth方式,并不是标准版的OAuth-3 legged。原因是通过2-legged,Gadget可以与Gadget的home server建立connection。
home server是指存放Gadget xml的server,开发者开发完gadget后会将gadget的xml源码放置于一个server,这与gadget在容器中运行时存在于容器中不是一个概念。
Signed Fetch允许gadget直接与自己的home server联系(类似直接打电话回家,因此叫phone home)。
此时,不需要“dance”的原因是,home server预先并不存在关于此用户的数据。因此也就不需要授权访问并不存在的数据。

 

 

OpenSocial REST API应用实例
OpenSocial容器开发REST API的两种主要应用实例

①为了获得gadget某使用者的用户信息, Gadget的home server向container发起server端到server端的的REST call。
举例:查询该用户的新朋友列表,这是Reverse Phone Home的应用(Phone Home:gadget to home server;Reverse Phone Home:home server get gadget user information)

②第三方的站点(没有gadget)想获得用户的允许以访问用户在social network上的私人数据。
举例:下载该用户的朋友列表。

 

第②个应用场景必须通过3-legged OAuth,
然而,第①个应用场景才是很多OpenSocial容器非常紧迫开放REST API的原因。
虽然在理论上,通过3-legged OAuth支持Reverse Phone Home是可行的,但是实际上使用3-legged是多余的并且将用户体验完全复杂化(试想一下call每个不同的REST API都需要用户点approve授权会是多可怕的一件事= =),在下面的章节中我们将解释为何这样说。

下面这张图是应用实例的数据流图

 

 

 

 

 

 

 

 

 

 

Reverse Phone Home

当用户在自己的页面添加一个gadget,在gadget会出现一些选项来控制gadget的访问级别,比如是否可以访问联系人列表,活动等。



 
也可以通过UI来设置gadget的home server对用户数据的访问权限
container可以对权限设置有默认选择,设置gadget的访问权限与home server相同。
如果用户在之后通过UI改变了这些权限设置,或者从自己的页面删除了gadget,home server会相应的做出改变。
这种两种设置相结合的做法,使得用户无需通过“dance”进行home server的访问权限设置。
更重要的是,提供了一种一致性的做法去修改或删除这些权限。因为对于用户来说。所有操作都在gadget中进行。Gadget外部不存在一个标准的如OAuth 3-legged那样的UI流程,通过专用的权限管理页面来管理权限设置。
这种一致性带来的好处显而易见,比如,如果用户在自己的页面上删除的gadget,但是忘记到权限管理界面删除home server对于用户数据的访问权限。
  
现在我们避免了OAuth dance,gadget的home server可以通过REST API访问OpenSocial容器中的用户数据。然而,这产生了两个安全和认证相关的问题
①container如何验证请求确实是从gadget的home server发过来?
②home server如何确认他得到的用户数据是他想要的?

 

对于第①个问题:OpenSocial container需要共享secret给gadget的开发者。从而,home server可以使用这个secret来对请求签名,也就表明了自己的身份。
一种做法是container的开发站点提供一个gadget的注册网站,开发人员登录后,输入自己gadget URL,随后container显示出一段代码,然后开发人员将这段代码添加至他们的gadget spec。随后container会检查gadget是否包含那段代码,如果找到,则验证了gadget确实是此开发人员所拥有。通过验证后,container会提供gadget的开发者一对OAuth Consumer Key& Secret。于是开发者可以将这对Key保存到home server上。
一个比较好的例子,MySpace's OpenSocial registration process.

注意:前面我们还提到Phone Home,即gadget通过container call home server,与上面的例子的方向相反,这些从container发出request也同样需要数字签名,container可以选择共享的secret做数字签名。

 

对于第②个问题是验证用户,幸运的是,在container和gadget的home server已经存在一个公共的用户识别符,当gadget对home server发起“phone call”,container会在请求中加上owner和viewer的id。因此home server能够本地保存用户id。如果home server想取该用户的更多数据,发起带上用户id参数的请求即可。

 

OpenSocial App Data

2-legged OAuth的另一个优势是,当OpenSocial container收到一个REST call,可以很方便的将发起这个call的服务器与gadget关联起来。如果home server请求访问OpenSocial的App Data,container需要知道返回哪个gadget的appdata,有了这个关联,就变得容易多了。此外,如果home server想增加信息到用户的活动,或者发送信息到用户,container可以将更新的信息传递至gadget。

 

 phone home 和 reverse phone home的参数对比:

 

 

OAuth 参数 Phone Home Reverse Phone Home
oauth_consumer_key Container Name:例 orkut.com opensocial_appid from phone home request
oauth_signature gadget specific shared secret gadget specific shared secret
opensocial_appid gadget ID assigned by container N/A
opensocial_ownerid user ID assigned by container N/A
opensocial_viewerid user ID assigned by container N/A
xoauth_requestor_id N/A opensocial_ownerid from phone home request


注意:
oauth_signature在两种case可以使用相同的共享secret。(有些container倾向于通过非对称密钥的方式签名phone home requests)
container可以指定用于reverse phone home calls的oauth_consumer_key,但是简单的方式是container发起phone home calls使用与之(oauth_consumer_key)相同的appid。

 

 

同时支持 3 legged & 2 legged
3 legged & 2 legged可以使用相同的API endpoint,只需要通过判断是否有OAuth token传递过来。
在3-legged OAuth中,OAuth token将传递过来,所请求的用户数据的ID可以从token中得到,但是发起REST CALL的server身份仍然需要再验证签名后从oauth_consumer_key得到。

  • 大小: 13.4 KB
  • 大小: 268.1 KB
  • 大小: 1.4 KB
  • 大小: 49 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics