zoukankan      html  css  js  c++  java
  • oAuth无痛入门指南

    http://atomti.iteye.com/blog/510070

    决心写个入门指南,理清思路。当然,如果你真的要仔细研究下oAuth,请看官方文档 http://oauth.net/core/1.0/ 。这里的东西最权威。也可以去oAuth邮件列表讨论。

    一句话oAuth

    oAuth涉及到3大块的交互和通信。1. 用户2. 拥有用户资料/资源的服务器A3. 求资源的服务器B,。

    oAuth的典型应用场景(senario)

    以前,用户拥有资源 的的网站A有一大堆东西;现在用户发现了一个新的网站B,比较好玩,但是这个新的网站B想调用 拥有资源的网站A的数据。

    例如,

    • 在线打印服务的网站,需要调用我的私人Flickr图片。
    • xiaonei.com之类的SNS在线社交网站需要从我的Hotmail导入联系人

    那么有以下几个方法:

    1. 需要转移的数据如果是一段文字的话,用户自己Ctrl+C, Ctrl+V。如果是图片呢?复制就麻烦了。
    2. 用户自己下载再上传。——麻烦
    3. 用户老老实实把自己账户ID和密码交上来,服务器自动去抓取。——这个等于把自己家的钥匙给别人来让别人借书一样。。。

    oAuth的方式

    用户在 求资源的网站B 上,点击一个URL,跳转到 拥有 资源的网站A。
    拥有资源的网站A提示:你需要把资源分享给B网站吗?Yes/No。
    用户点击 Yes拥有资源的网站A求资源的网站B 临时/永久 开一个通道,然后 求资源的网站 就可以来 拥有资源的网站 抓取所需的信息了。

    那么具体的说就有3个步骤:

    1. 首先是2个服务器之间的。求资源的网站B向拥有资源的网站A发送一个请求。术语叫Obtaining an Unauthorized Request Token。具体的作用,类似写了一个“资源远程调用申请书”给 拥有资源的A网站
    2. 第二步是,用户在拥有资源的网站A 通过/允许这个请求。术语叫Obtaining User Authorization。类比一下,就是用户给这个申请书盖章通过啦。
    3. 最后一步仍然是服务器之间的通信。回到B网站,求资源的网站B临时/永久拥有了在A网站远程调用资源的权限,术语又叫Obtaining an Access Token。就好比得到了一个“黄金招牌(Access Token)”。只要每次带上这个“黄金招牌”,求资源的网站B 就可以大摇大摆去 拥有资源的网站A 抓取任意有权限可以被抓取的资源了。具体的技术细节,就是拥有资源的服务器A返回了类似这样的一个application/x-www-form-urlencoded字符串:oauth_token_secret=ssssssssss&oauth_token=ttttttttttttttt&other_parameters=1331775,这个时候,oauth_token 就相当于用户的密码,你可以用这个oauth_token做任意权限之内的事情了。oauth_token_secret是私钥。other_parameters是服务器返回的其它可选参数。一般来说,你可以把这个oauth_token的值保存起来,下次接着用。而且一般来说一个用户和一个oauth_token是一一对应的。

    oAuth flow

    传递oAuth参数

    Technically。当然2个服务器之间传输数据的时候,这里面有一些秘密的oAuth参数以保障整套体系是安全可靠的。这些参数叫Consumer Request Parameters(在oAuth 1.0规范5.2里定义的)。具体的来说,传递oAuth参数有3种方法:

    1. 通过HTTP GET,在URL里面,? 后面的一堆参数。个人不推荐这种方法,因为用一个iframe或者img就可以被XSS了。
    2. HTTP POST方法,参数Content-Type格式为application/x-www-form-urlencoded
    3. 通过Authorization这个HTTP头。传递的东西有一定的格式要求,叫OAuth HTTP Authorization Scheme

    这套体系有个比较龌龊的特性,对开发人员十分麻烦,但是对保密性做得比较好,叫“签名”。而且这个特性不是可选的,是必须的。

    签名

    什么是 签名(Signature)
    数字签名不是指将你的签名扫描成数字图像,或者用触摸板获取的签名,更不是你的落款。
    数字签名在防止篡改,防止重放攻击,保证数据完整性,防止假冒签名,防止签名者抵赖方面更有效。在中国大陆,数字签名是具法律效力的。

    目的:在保证安全(不泄漏密码,防止中间人攻击)的前提下,尽量简单的设计一套可靠“授权”体系。

    oAuth官方定义了3种方式,分别是HMAC-SHA1, RSA-SHA1PLAINTEXT。当然各个支持oAuth的服务器也可以自定定义一套体系。但是签名的大概过程都差不多。

    需要签名的数据依次是:

    1. HTTP方法是GET, POST还是HEAD?
    2. 规范化表示的HTTP URL
    3. 编码合并过后的oAuth参数列表

    这3部分需要用 & 符号连接起来,然后交给hmac或者RSA加密。当然我讨厌这么麻烦的方式,所以我用最后一种,也是最简单,各个oAuth服务基本都支持的“签名”方式:PLAINTEXT

    具体的很简单,每次请求的时候,oAuth参数包括一个oauth_signature就行了。值就是拥有资源服务器提供的secret key

    再次讨论oAuth参数:术语解释

    oauth_consumer_key
    求资源的网站B的一个标识符。可以认为世界上有许许多多类似 网站B 这样的需求。每一个服务都给了一个唯一的标识符。这个东西哪里来的?自己去问 拥有资源的网站A。例如douban就提供了一个Douban API Key,这里就填Douban API Key好啦。
    oauth_consumer_secret
    上面那个东西的私钥。如果是Douban,就填API Key的私钥。
    oauth_token
    oAuth进行到最后一步得到的一个“黄金招牌”。有了这个“黄金招牌”,求资源的网站B就可以大摇大摆去 拥有资源的网站A 抓取任意有权限可以被抓取的资源了。
    oauth_token_secret
    上面那个东西的私钥
    oauth_signature_method
    签名方法。三选一:SHA1, RSA-SHA1或者PLAINTEXT。哦。不对。不是三选一,oAuth服务商可以自定义的。
    oauth_signature
    签名值。这个得靠你自己把数据揉到一个加密函数里算出来。具体如何算看这里
    oauth_timestamp
    时间戳。timestamp。不懂的自己google。
    oauth_nonce
    这个就是一个临时值,只要保证每次请求,这个值都不一样就行了。一般随机生成一截数字。

    实践

    说了这么一大堆东西,还是应该弄一个library来完成这一系列工作。哈哈。不要重复发明轮子嘛。例如oauth-python。我个人觉得很可惜的是,如果你有把这个库弄懂,会用那个精力,还不如自己实现一个库算了。汗。

    oAuth的其他

    oAuth在安全领域里,是一套相当有Web特征的“授权(authorization)”体系。

    oAuth有个好处,就是认证不一定是基于Web的,假如你写了个桌面程序,或者说widget,或者说javascript webapps,也可以直接采用oAuth。其实est个人在想的话,如果采用各个浏览器的cookiejar文件解析 + Flash的LSO,加上oAuth,基本可以做到一次登录永久授权了。

    oAuth的诞生可以说是豪门云集啊。一出来的目标就是统一各个网络服务商的各自的登录/授权/认证API,例如Digg, Jaiku, Flickr, Ma.gnolia, Plaxo, Pownce, Twitter, Google, Yahoo, and others soon to follow。不服气的可以再去看看oAuth 1.0规范的作者列表,那些email地址都是牛B闪闪的大公司大巨头牛人啊。

    国内的话,Douban采用的是oAuth,虽然用起来有点麻烦,但是支持oAuth应该算一个非常国际化标准化的举措了。

    问题在哪里?

    假如有一个网站,既扮演了求资源的服务器A这个角色,又扮演了用户角色。加上X技术Y方法Z漏洞。。。。。

  • 相关阅读:
    ZOJ 3332 Strange Country II
    ZOJ 3331 Process the Tasks(双塔DP)
    ZOJ 3326 An Awful Problem(模拟)
    HDU 1796 How many integers can you find(容斥原理)
    HDU 4059 The Boss on Mars(容斥原理)
    HDU 4135 Co-prime(容斥原理)
    HDU 5677 ztr loves substring(回文串加多重背包)
    CodeForces 668B Little Artem and Dance
    CodeForces 667A Pouring Rain
    Java实现 LeetCode 764 最大加号标志(暴力递推)
  • 原文地址:https://www.cnblogs.com/gitran/p/3644162.html
Copyright © 2011-2022 走看看