OAuth2授权(Client Credentials)

来源:互联网 发布:linux测试网速的命令 编辑:程序博客网 时间:2024/06/14 20:40

OAuth 2.0定义了四种授权方式。

1.授权码模式(authorization code)
2.简化模式(implicit)
3.密码模式(resource owner password credentials)
4.客户端模式(client credentials)

ClientCredentials客户端模式:
Client使用自己的 client证书(如 client_id及client_secret组成的 http basic验证码)来获取 access token,只能用于信任的client
场景:

认证服务器不提供像用户数据这样的重要资源,仅仅是有限的只读资源或者一些开放的API。例如使用了第三方的静态文件服务,如Google Storage或Amazon S3。这样,你的应用需要通过外部API调用并以应用本身而不是单个用户的身份来读取或修改这些资源。这样的场景就很适合使用客户端证书授权。

1. 用客户端证书交换访问令牌

应用程序需要向认证服务器申请访问令牌,而该请求则需要客户端证书进行认证。

假设现在我们正在折腾环信IM,其认证URL为:

https://a1.easemob.com/pair/pair/token

这里需要使用POST请求并附带以下参数:

grant_type

这里为“client_credentials”

client_id

应用注册时获得的client id

client_secret

应用注册时获得的client secret

以下是一个通过命令行HTTP客户端curl发起的请求示例:

curl -d "grant_type=client_credentials\&client_id=2016273333331117128396\&client_secret=904b98aaaaaaac1c92381d2" \https://a1.easemob.com/pair/pair/token
 POST /token HTTP/1.1 Host: a1.easemob.com/pair/pair/token Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded;charset=UTF-8 grant_type=client_credentials

其中Authorization是client_id及client_secret组成的http_basic验证串。grant_type必须为client_credentials!

如果认证成功,服务器将会返回令牌access_token:

     HTTP/1.1 200 OK     Content-Type: application/json;charset=UTF-8     Cache-Control: no-store     Pragma: no-cache     {       "access_token":"2YotnFZFEjr1zCsicMWpAA",       "token_type":"example",       "expires_in":3600,       "example_parameter":"example_value"     }

2.国内一些OAUTH2案例分析(以下案例摘抄自网络)

标准的 oauth2中,使用 access token来向资源服务器发出请求,取得资源。这里的资源服务器需要使用 https协议,否则access token极可能被其它方获取。比如环信注册用户

GET /resource/1 HTTP/1.1Host: a1.easemob.com/pair/pair/usersAuthorization: Bearer 7Fjfp0ZBr1KtDRbnfVdmIw

bearer是指 token类型,后面的字符串就是access token。

还有一种 mac类型的 token(目前v20版本的草稿里还没有文档),如:

GET /resource/1 HTTP/1.1Host: example.comAuthorization: MAC id="h480djs93hd8",                   nonce="274312:dj83hs9s",                   mac="kDZvddkndxvhGRXZhvuDjEWhGeE="

,因为 https速度相较http慢,而且并非所有服务器或客户都支持https,所以国内一些网站采用一种http也可访问资源的方式。

淘宝开放平台的方式
:应用通过用户授权获取的AccessToken的值即等同于Sessionkey,应用凭借AccessToken调用taobao API即可。查看淘宝SDK,可以看到 其使用应用的app_secret作用密码钥来进行签名,参数里面包含了 这个Sessionkey,这样淘宝在收到这个请求的时候,根据 app_id来判断是哪个应用,根本sessionkey的值来判断是哪个用户,如果不传这个 sessionkey就用 app_id查得app_id所属的淘宝用户就行了。也就是说 sessionkey必须配合 这个 client自己的授权资料appkey appsrecet来访问资源。

百度开放平台方式、人人网方式、还有腾讯也类似:在返回 access token的同时返回 sessionKey及sessionSecret。如:

{    "access_token": "1.a6b7dbd428f731035f771b8d15063f61.86400.1292922000-2346678-124328",    "expires_in": 86400,    "refresh_token": "2.385d55f8615fdfd9edb7c4b5ebdc3e39.604800.1293440400-2346678-124328",    "scope": "basic email",    "session_key": "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=",    "session_secret": "27e1be4fdcaa83d7f61c489994ff6ed6",}

在调用资源API的时候,如下:

GET /rest/2.0/passport/users/getInfo?session_key=9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A%3D&timestamp=2011-06-21+17%3A18%3A09&format=json&uid=67411167&sign=d24dd357a95a2579c410b3a92495f009 HTTP/1.1Host: api.example.com

这里参数里面的 session_key,传给服务器后,用户查询 session_secret,sign使用session_secret作为密钥来加密的。可以看到这里调用的时候没有使用 client_id或client_secret信息,所以对于任何获取

"session_key": "9XNNXe66zOlSassjSKD5gry9BiN61IUEi8IpJmjBwvU07RXP0J3c4GnhZR3GKhMHa1A=","session_secret": "27e1be4fdcaa83d7f61c489994ff6ed6",

的一方都可以调用到API。降低系统耦合度。

1 0