在固件版本 6.0 中,WebSphere® DataPower 提供了扩展点来自定义 OAuth 协议阶段的标准处理。在本教程中,我们将介绍如何扩展或自定义这些操作。您可以为 Additional OAuth Process 字段选择一个样式表值来启用此特性,如图 1 所示。此字段显示在 OAuth 客户端配置文件对象的 Advanced 选项卡上。
图 1. OAuth 扩展点字段
要使用 DataPower 作为授权服务器,它需要提供以下功能:
通过填充 Additional OAuth Process 字段,您可以提供一个样式表来支持您希望覆盖的操作。如果该操作未在样式表中指定,DataPower 将使用它的标准行为。
支持的操作包括:
以下两个操作仅在 “OAuth Client Profile” 中的 “Caching” 设置为 “Custom” 时使用。这表明您希望提供一个自定义进程来处理撤销。
回页首
在授权代码授予类型场景中,向 OAuth 客户端提供一个临时授权代码来交换访问令牌。
授权代码使用以下 HTTP 302 重定向返回给 OAuth 客户端:
HTTP/1.1 302 Processed Location: https://<client-hostname-redirect-url>? code=........&state=........
authorization_request扩展点允许您向授权代码授予响应附加更多信息。
<input> <operation>authorization_form</operation> <oauth-id>........</oauth-id> <OauthSupportedClient>........</OAuthSupportedClient> </input>
<result> <name1>text</name1> ... <name-9>text</name-9> </result>
对于上述输出,将按如下方式扩充 302 重定向:
HTTP/1.1 302 Processed Location: https://<client-hostname-redirect-url>? code=........&state=........&name1=text&name-9=text
回页首
对于所有支持的授予类型,在成功执行 OAuth 握手后,将在一个 JSON 对象中或作为重定向 URI 的一部分返回一个访问令牌:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"........", "token_type":"bearer", "expires_in":3600, "refresh_token":"........" }
access_request扩展点允许您向访问令牌响应添加更多信息,或者执行更多处理。在本教程中提供的样式表示例中,它向 access_token 有效负载响应添加了更多信息。
<input> <operation>access_request</operation> <result> <access_token>........</access_token> <expires_in type='json:number'>........</expires_in> <scope>........</scope> </result> ….. </input>
<result> <custom1>text</custom1> ... <custom9 type='json:number'>88</custom9> </result>
对于上述输出,访问令牌 JSON 对象将扩充为以下内容:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store Pragma: no-cache { "access_token":"........", "token_type":"bearer", "expires_in":3600, "refresh_token":"........", "custom1":"text", … "custom9":88 }
回页首
设备成功验证一个 access_token 后,但在将请求发送给后端设备服务器之前,此操作提供了一个在发送请求前处理有效负载的机会。此操作不需要输出,返回的任何输出都会被 DataPower 忽略。可以使用此操作为后端应用服务器设置更多 HTTP 标头。
<input> <operation>resource_request</operation> ..... <container> same input for AAA – PostProcess Custom stylesheet ... </container> </input>
回页首
对于授权代码和隐式授予类型,资源所有者将获得一个授权表,资源所有者可在其中授予 OAuth 客户端请求的资源的访问权。默认情况下,DataPower 允许资源所有者仅授予客户端请求的范围的子集。
authorization_form扩展点允许您在将授权表返回给设备时调整该选择。
<input> <operation>authorization_form</operation> <oauth-id type="authorization_request"> <response_type>...</response_type> ........ <authorization-request> <args src="body"> ........ </args> </authorization-request> </oauth-id> <OAuthSupportedClient>….....</OAuthSupportedClient> </input>
<result> <scope>....supported scopes separated by space....</scope> </result>
预期输出中指定的范围将用作 OAuth 握手支持的范围。
回页首
对于授权代码和隐式授予类型,将为资源所有者提供一个授权表来批准客户端的请求。DataPower 支持预先批准或预先拒绝这些请求。通过标记一个请求已预先批准还是预先拒绝,DataPower 将跳过向资源所有者显示授权表的过程,前进到 OAuth 进程中的下一步。
preapproved_check扩展点允许您缩短授权授予过程,以便可批准或拒绝一些请求。当客户端尝试访问资源时,在这些情况下不会出现授权表。
<input> <operation>preapproved_check</operation> <container> ... same input for AAA – PostProcess Custom stylesheet ... </container> </input>
<result><approved>yes|no|unknown</approved></result>
各个选择具有以下含义:
回页首
从固件版本 6.0.0 开始,DataPower 为 OAuth 客户端提供了一种验证其拥有的访问令牌的方式。添加了一种新授予类型 urn:ibm:datapower:validate
来支持此验证请求。请参阅下面的示例 curl 命令,了解使用这种自定义授予类型调用 DataPower 的详细信息。
validate_request扩展点允许您在成功验证访问令牌后,向响应添加更多信息或执行更多处理。
对于以下请求:
curl -k -v https://<dp>:<port>/<uri>?client_id=<client_id>&grant_type= urn%3Aibm%3Adatapower%3Avalidate&access_token=......
这是输出示例:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store, no=cache Pragma: no-cache { "valid":true, "token_type":"bearer", "client_id":"<client_id>", "not_after":"178947675", "not_after_text":"2012-09-02T03:41:15Z", "not_before":"178944075", "not_before_text":"2012-09-02T02:41:15Z", "resource_owner":"spoon", "scope":"/getAccountInfo" }
<input> <operation>validate_request</operation> <container> .. same input for AAA – PostProcess Custom stylesheet …..... </container> </input>
<result> <extra1>customerid</extra1> ... <extra8 type='json:number'>8888</extra8> </result>
对于上述输出,响应将扩充为以下内容:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Cache-Control: no-store, no=cache Pragma: no-cache { "valid":true, "token_type":"bearer", "client_id":"<client_id>", "not_after":"178947675", "not_after_text":"2012-09-02T03:41:15Z", "not_before":"178944075", "not_before_text":"2012-09-02T02:41:15Z", "resource_owner":"spoon", "scope":"/getAccountInfo" "extra1":"customerid", ..... "extra8":8888 }
回页首
从固件版本 7.0.0 开始,DataPower 提供了一种在受密码保护的令牌中添加更多信息的方法。该方法允许您添加至多 512 字符的数据。例如,如果有一个会话被持久保存在数据库中的某处,您可以使用此字段将该条目的索引存储到数据库中。
access_token
信息的一部分,它还会影响 refresh_token
。 如果在 dp-state
期间添加了杂项信息,DataPower 将自动将该值传递给 az-code
和 access-token
。但是,如果需要的话,您可以在 @type=az-code
或 @type=access-token
期间忽略该信息。
如果在 az-code
期间添加了其他信息,DataPower 会自动将该值传递给 access_token
和 refresh_token
,除非它在以后的 @type=access-token
期间被覆盖。
<input> <operation @type='dp-state|az-code|access_token'> validate_request </operation> <container> .. same input for AAA – PostProcess Custom stylesheet …..... </container> </input>
<result> <miscinfo>up to 512 characters long of data</miscinfo> </result>
要在持久调用信息上利用自定义的撤销支持,您可以升级到 DataPower 固件的以下修复包:6.0.0.15、6.0.1.11、7.0.0.8、7.1.0.5。该撤销分解为 3 个不同的操作。在这一节中,我们将介绍如何将撤销信息从 DataPower 持久保存到永久存储中,以便您可以在高可用性 (HA) 环境中提供撤销支持。对于任何文件访问,网络访问都是应用程序最耗时的任务之一。DataPower 仅在绝对必要时触发以下操作。
在大多数情况下,撤销的访问只是不同资源所有者向许多应用程序授予的所有访问权的一小部分。没有必要存储来自 OAuth 的所有授权令牌,将它们用于此用途。通过提供跟踪撤销的选项,DataPower 在撤销的处理上提高了灵活性(不是一个 “一体适用” 的解决方案)。
revoke_request
) check_revocation_request
) access_request
) 为了提供最佳性能和在集群环境中实现 HA 灵活性,DataPower 在使用任何上述操作执行撤销检查之前,首先应利用它的运行时缓存,如图 2 中所示。
图 2. 撤销检查
回页首
此操作处理撤销的记录。有两种类型的撤销:客户端/应用程序撤销它收到的令牌,以及资源所有者撤销一个客户端/应用程序。此操作在 DataPower 确认令牌有效而且没有过期之后触发。由于此设计,对于基于文件和基于网络的高成本且耗时的操作,仅在认为该令牌值得此开销时才会发生。您可以利用此行为让您的实现更加健全。例如,对于资源所有者撤销,可以考虑存储资源所有者撤销权限时的时间戳。检查一个令牌是否撤销(在操作 check_revocation_request 中)时,使用此信息拒绝在上述时间戳之前发放的所有令牌。这允许拥有新权限的应用程序访问资源。
点击查看代码清单
关闭 [x]
<input> <operation>revoke_request</operation> <!—optional access_token and refresh_token, since client can revoke access_token only, refresh_token only, or both <access_token count="1" src="body">...</access_token> <refresh_token count="1">....</refresh_token> <client_id src="basic-auth" count="1">client</client_id> <oauth-id type="client_revoke_request"> <access_token count="1" src="body">...</access_token> <refresh_token count="1">....</refresh_token> <grant_type count="1">urn:ibm:datapower:client:revoke</grant_type> <client_id src="basic-auth" count="1">client</client_id> <client_secret src="basic-auth" sanitize="true" count="1>..</client_secret> <original-url count="1" type="request">https://dp:7777/revoke</original-url> </oauth-id> <OAuthSupportedClient>....</OAuthSupportedClient> </input>
点击查看代码清单
关闭 [x]
<input> <operation>revoke_request</operation> <resource_owner>tonyf</resource_owner> <client_id count="1" src="body">client</client_id> <entry type="oauth"> <oauth-id type="owner_revoke_request"> <grant_type count="1">urn:ibm:datapower:owner:revoke</grant_type> <client_id count="1" src="body">client</client_id> <original-url count="1" type="request">https://dp:7777/revoke</original-url> </oauth-id> <OAuthSupportedClient><client-id>..</client-id>......</OAuthSupportedClient> <oauth-verified state="ok"> <result> <grant_type count="1">urn:ibm:datapower:owner:revoke</grant_type> <client_id count="1" src="body">client</client_id> </result> </oauth-verified> </entry> </input>
<result><status>success|failure</status></result>
回页首
在 OAuth 或资源访问处理过程中,DataPower 需要验证令牌(或访问)是否已撤销。此操作提供了必要的信息供 DataPower 继续处理。仅在 DataPower 验证令牌有效,而且因为在 DataPower 运行时缓存中被重用而未撤销时,才会调用此操作。
<input> <operation token-type="access_token|refresh_token|az-code|dp-state">check_revocation_request</operation> <token>....</token> <verified-token> <client_id>…</client_id> <not_after>….</not_after> <not_after_text>….</not_after_text> <not_before>…</not_before> <not_before_text>2014-08-08T08:08:08Z</not_before_text> <resource_owner>xx</resource_owner> <scope>xx</scope> <miscinfo>..</miscinfo> </verified-token> <oauth-id type="...">.....</oauth-id> <OAuthSupportedClient>...</OAuthSupportedClient> </input>
拥有节点 <revoked/>
表明令牌已撤销。
<result><revoked/></result>
如果令牌未撤销,则无需要返回任何节点集。
回页首
此操作是可选的。但是,我们强烈建议使用它。此操作在为已验证的操作生成访问令牌时发生。在两种情况下,您都应该考虑将信息保存在外部存储中:创建 access_token
作为授权代码授予类型的一部分时,或者对于 refresh_token
授予类型。您可能希望将授权代码或 refresh_token
的副本保存在与其他令牌相同的撤销存储中。
回页首
本系列的最后一部分(第 10 部分)描述了可以为了修改标准 DataPower OAuth 支持而覆盖的操作。您可以使用本教程中提供的样式表,使用扩展点(无论是单独使用还是组合在不同组合中)来满足您的业务需求。
感谢 Paul Glezen 对本文的审阅。
回页首
描述 | 名字 | 大小 |
---|---|---|
代码示例 | code_sample.zip | 7KB |