本文是Windows Azure AppFabric入门教学的第四篇文章。我们知道AppFabric中的Access Control Service在验证授权过程中会使用到SWT 和OAuth WRAP,所以为了更好的了解ACS其内部原理,我们会在本教程中简单地介绍SWT 和OAuth WRAP协议。
Simple Web Token (SWT)
SWT简介:
Simple Web Token (SWT)定义了传输简单声明的格式,其兼容性和格式能够轻易的被放入例如HTTP等协议的头部。一个简单的声明可以由一组名值对组成。
因为 SWT会传输重要的验证和访问信息,我们需要防止其被篡改。因此引入了唯一的强制的名值对- HMACSHA256。这一般为SWT最后一对名值对,其值为其他名值对的SHA 256 HMAC 值。
SWT 示例:
一SWT 发布者想要发布一个SWT,并带有如下信息
Issuer = issuer.example.com
ExpiresOn = 1/1/2010, Midnight
com.example.group = gold
over18 = true
其 HMAC 密钥为 (base 64编码表示,该密钥客户端和服务器端各有一份) :
N4QeKa3c062VBjnVK6fb+rnwURkcwGXh7EoNK34n0uM=
在本示例中, Issuer 和 ExpiresOn 是SWT规范的保留字。 com.example.group属性是 example.com域名拥有者所指定的句法和语义上的协定。 over18是一个在发布者和用户之间,私下定义的属性
在对SWT进行编码前,我们需要将 ExpiresOn 转换成从UTC时间1970年1月1日午夜至失效时间2010年1月1日午夜的秒数。结果是 1262304000。
编码
1.将名值对编码。结果如下:
Issuer=issuer.example.com&ExpiresOn=1262304000&com.example.group=gold&over18=true
2. 使用密钥来计算先前值的HMAC值。
3. 用Base64编码来表示上一步的 HMAC。结果为: AT55+2jLQeuigpg0xm/vn7tjpSGXBUfFe0UXb0/9opE=
4. 将上步结果以URL编码,并附在声明的最后。最终结果如下:
Issuer=issuer.example.com&ExpiresOn=1262304000&com.example.group=gold&over18=true&HMACSHA256= AT55%2B2jLQeuigpg0xm%2Fvn7tjpSGXBUfFe0UXb0%2F9opE%3D
解码
1. 用 &HMACSHA256= 来分开SWT,我们得到一个noHMACSWT 字符串:Issuer=issuer.example.com&ExpiresOn=1262304000&com.example.group=gold& =over18=true&
以及一个 submittedHMAC 字符串: AT55%2B2jLQeuigpg0xm%2Fvn7tjpSGXBUfFe0UXb0%2F9opE%3D
2. 用URL解码 submittedHMAC 字符串,得到: AT55+2jLQeuigpg0xm/vn7tjpSGXBUfFe0UXb0/9opE=
3. 使用计算noHMACSWT字符串和HMAC密钥来计算 localHMAC, 以base64编码表示,结果如下:
AT55+2jLQeuigpg0xm/vn7tjpSGXBUfFe0UXb0/9opE=
4. 比较 submittedHMAC 和 localHMAC ,我们看到它们是一致的,因此验证通过。之后URL解码noHMACSWT字符串来获得 SWT值。 如果在传输过程中(在编码后和解码前),SWT的值被中间节点修改了(例如把over18=true改为over18=false)那么最终localHMAC计算的结果将与submittedHMAC不同(因为中间节点不知道HMAC密钥,因此无法伪造submittedHMAC),这样一来服务器端就能知道消息被篡改。
OAuth Web Resource Authorization Profiles (OAuth WRAP)
OAuth WRAP简介:
随着互联网的发展,越来越多应用程序(客户端)以HTTP协议或其他协议通过API来访问资源。这些资源通常需要验证,它们被称为受保护资源(Protected
Resources)。OAuth WRAP使得受保护资源可以将授权工作委托给一家或多家受托的授权机构。
希望访问受保护资源的客户端首先从受托的授权机构处(授权服务器)获得授权。一旦经授权,客户端获得一个Access Token以及一个用来获取新Access Token的Refresh Token。
为方便重用其他合适的Token,Access Token可以是任何格式的,例如Simple Web Token或者是JSON Web Token。下图展示了客户端和授权服务器(A,B)之间的,以及客户端和受保护资源(C,D)之间的通信流程。
步骤A,客户端向授权服务器提供了凭证。步骤B中授权服务器返回给客户端Access Token。步骤C,客户端在HTTP头中附加得到的Access Token,传送给受保护资源。步骤D,受保护资源监察该头确认Access Token有效性,如果通过验证就返回客户端期望的结果。
在OAuth WRAP规范文档中定义了许多档案(Profile),某一档案(Profile)会规定通信的细节。ACS当前版本中只支持部分档案。客户端账户和密码档案为常用档案之一(Client Account and Password Profile)。
下面我们具体讲解一下Client Account and Password Profile。
1.在使用该profile之前,客户端必须从授权服务器处获得一个账户名和账户密码。
2. 客户端使用POST来向授权服务器的Access Token URL发送HTTPS请求。请求包括如下参数:
wrap_name:必须
wrap_password:必须
wrap_scope:可选
3. 如果请求成功授权服务器返回:
HTTP 200 OK
以及在响应主体中带有Access Token,并包含如下参数:
wrap_access_token:必须
wrap_access_token_expires_in:可选
4. 如果失败,返回:
HTTP 401 Unauthorized
以及HTTP头部:
WWW-Authenticate: WRAP
下面我们用一示例来具体讲解OAuth WRAP中client account and password profile的验证流程。
1. 在本示例中,crm.example.com是拥有受保护资源的应用程序服务器,其受保护资源位于https://crm.example.com/data。 DataDumper是作为一个客户端运行,其周期性的调用https://crm.exanmple.com/data.受保护资源委托授权服务器auth.example.net来验证客户端是否有访问权。
2. 授权服务器文档定义Access Token URL 为https://auth.example.net/access_token。授权服务器也定义了调用Access Token URL时必须带有Audience参数。客户端获得如下信息:
Client Account: datadumper
Client Password: j2hw7GPsl0
受保护资源和授权服务器同意使用Simple Web Token(SWT)来作为Access Token,并带有保留属性:Issuer,Audience,ExpiresOn以及公开属性net.example.auth.account, HMAC密钥: (base64编码表示):3iK5ZYAoBQuOqSgF/YqlDw70HKRmbyXkrl5f4SJ4Toc=
3. 客户端请求Access Token。客户端向https://auth.example.net/access_token发送HTTPS POST请求,并带有如下信息:wrap_name=datadumper&wrap_password=j2hw7GPsl0&Audience=crm.example.com
4. 成功响应。授权服务器检查客户密码j2hw7GPsl0以及客户名datadumper是否被授权访问crm.example.com.授权服务器注意到时间是2010--‐02--‐03T04:05:06Z,从1970--‐01--‐01T0:0:0Z.时算起,其为1265198706秒。授权服务器希望Access Token一小小时候失效,所以以3600加在当前时间上。服务器便使用如下信息:
net.example.auth.account: datadumper
ExpiresOn:1265202306(1265198706+3600)
Audience:crm.example.com
Issuer:auth.example.net
以及协商的HMAC密钥来产生如下SWT:
net.example.auth.account=datadumper&ExpiresOn=1265202306&Audience=crm.
example.com&Issuer=auth.example.net&HMACSHA256=N9%2F%2F0tSos78Me36%2Bi
oBH0sFKfd7eCsURlEIheoUbCJk%3D
授权服务器以HTTP 200 OK来响应客户端的HTTPS请求。
Access Token和其生命周期以application/x--‐www--‐form--‐urlencoded格式置于信息的主体内:
wrap_access_token=net.example.auth.account%3Ddatadumper%26ExpiresOn%3D
1265202306%26Audience%3Dcrm.example.com%26Issuer%3Dauth.example.net%26
HMACSHA256%3DN9%252F%252F0tSos78Me36%252BioBH0sFKfd7eCsURlEIheoUbCJk%2
53D&wrap_access_token_expires_in=3600
5. 客户端调用受保护资源:客户端拥有一小时有效的Access Token。其使用API来调用https://crm.example.com/data,并包含如下HTTP头部:
Authorization: WRAP access_token="net.example.auth.account=datadumper&
ExpiresOn=1265202306&Audience=crm.example.com&Issuer=auth.example.net&
HMACSHA256=N9%2F%2F0tSos78Me36%2BioBH0sFKfd7eCsURlEIheoUbCJk%3D"
受保护资源验证SWT,并按照SWT内的授权属性完成客户端的请求。
相关协议可以从下面地址得到。有兴趣的读者可以参考:
http://groups.google.com/group/oauth-wrap-wg/files