© 2016 IBM Corporation 118
外部リポジトリーの利用 (2/11)
IDG設定方法
OAuthクライアント・プロファイルにて設定
メニューより「オブジェクト」 > 「暗号構成」 > 「OAuthクライアント・プロ ファイル」で、カスタマイズしたいプロファイルを選択表示し、「拡張」タブの
「キャッシング」にて「カスタム」を選択
「追加OAuth処理」にてカスタマイズしたXSLTファイル (または GatewayScript)を選択
XSLTファイル (またはGatewayScript)にて”revoke_request”
/ ”check_revocation_request” / “access_request”処理の操作をカスタマイズし、
外部リポジトリーに問い合わせる
6. access_request処理 9. check_revocation_request処理
10. revoke_request処理
外部リポジトリーの利用 (3/11)
revoke_addprocess.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:dpconfig="http://www.datapower.com/param/config"
xmlns:dpfunc="http://www.datapower.com/extensions/functions"
extension-element-prefixes="dp dpfunc"
exclude-result-prefixes="dp dpfunc dpconfig">
<xsl:variable name="cache-server-url" select="'http://192.168.10.200:7088'"/>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="/input/operation = 'revoke_request'">
<!-- call to store the information -->
<result>
<xsl:choose>
<xsl:when test="/input/resource_owner and /input/client_id">
<xsl:variable name="url-query">
<xsl:value-of select="$cache-server-url"/>
<xsl:text>/owner-revoke?client_id=</xsl:text>
<xsl:value-of select="/input/client_id"/>
<xsl:text>&resource_owner=</xsl:text>
<xsl:value-of select="/input/resource_owner"/>
<xsl:text>&access_token_ttl=</xsl:text>
<xsl:value-of select="/input/entry/OAuthSupportedClient/access-token-lifetime"/>
<xsl:if test="/input/entry/OAuthSupportedClient/refresh-token-lifetime">
<xsl:text>&refresh_token_ttl=</xsl:text>
<xsl:value-of select="/input/entry/OAuthSupportedClient/refresh-token-lifetime"/>
</xsl:if>
</xsl:variable>
外部リポジトリーの宛先URLを指定
revoke_request処理のカスタマイズ
外部リポジトリーに対する
リクエストURLの形成
© 2016 IBM Corporation 120
外部リポジトリーの利用 (4/11)
revoke_addprocess.xsl (続き)
<!-- in reality, we should check for the return code to make sure the cache is actually stored -->
<xsl:variable name="message-response">
<dp:url-open target="{$url-query}"
response="responsecode-ignore">
</dp:url-open>
</xsl:variable>
<status>success</status>
</xsl:when>
<xsl:when test="/input/access_token or /input/refresh_token">
<xsl:variable name="url-query">
<xsl:value-of select="$cache-server-url"/>
<xsl:text>/client-revoke?</xsl:text>
<xsl:if test="/input/access_token">
<xsl:text>access_token=</xsl:text>
<xsl:value-of select="/input/access_token"/>
<xsl:text>&access_token_ttl=</xsl:text>
<xsl:value-of select="/input/OAuthSupportedClient/access-token-lifetime"/>
</xsl:if>
<xsl:if test="/input/refresh_token">
<xsl:if test="/input/access_token">
<xsl:text>&</xsl:text>
</xsl:if>
<xsl:text>refresh_token=</xsl:text>
<xsl:value-of select="/input/refresh_token"/>
<xsl:text>&refresh_token_ttl=</xsl:text>
<xsl:value-of select="/input/OAuthSupportedClient/refresh-token-lifetime"/>
</xsl:if>
</xsl:variable>
<xsl:message dp:priority="info"><xsl:value-of select="$url-query"/></xsl:message>
(次頁へ続く)
外部リポジトリーへアクセス
外部リポジトリーの利用 (5/11)
revoke_addprocess.xsl (続き)
<!-- in reality, we should check for the return code to make sure the cache is actually stored -->
<xsl:variable name="message-response">
<dp:url-open target="{$url-query}"
response="responsecode-ignore">
</dp:url-open>
</xsl:variable>
<status>success</status>
</xsl:when>
<xsl:otherwise>
<status>failure</status>
<error>invalid_request</error>
<error_description>not enough info for operation</error_description>
</xsl:otherwise>
</xsl:choose>
</result>
</xsl:when> <!-- End of revoke-request -->
<xsl:when test="/input/operation = 'access_request'">
<xsl:choose>
<xsl:when test="/input/container/identity/entry[@type='oauth']/oauth-id[@type='access_request']/grant_type = 'refresh_token'">
<!-- record the refresh token as revoked -->
<xsl:variable name="url-query">
<xsl:value-of select="$cache-server-url"/>
<xsl:text>/client-revoke?</xsl:text>
<xsl:text>refresh_token=</xsl:text>
<xsl:value-of select="/input/container/identity/entry[@type='oauth']/oauth-id[@type='access_request']/refresh_token"/>
<xsl:text>&refresh_token_ttl=</xsl:text>
<xsl:value-of select="/input/container//OAuthSupportedClient/refresh-token-lifetime"/>
access_request処理のカスタマイズ
© 2016 IBM Corporation 122
外部リポジトリーの利用 (6/11)
revoke_addprocess.xsl (続き)
<xsl:message dp:priority="info"><xsl:value-of select="$url-query"/></xsl:message>
<!-- in reality, we should check for the return code to make sure the cache is actually stored -->
<xsl:variable name="message-response">
<dp:url-open target="{$url-query}"
response="responsecode-ignore">
</dp:url-open>
</xsl:variable>
</xsl:when>
<xsl:when test="/input/container/identity/entry[@type='oauth']/oauth-id[@type='access_request']/grant_type = 'authorization_code'">
<!-- record the refresh token as revoked -->
<xsl:variable name="url-query">
<xsl:value-of select="$cache-server-url"/>
<xsl:text>/client-revoke?</xsl:text>
<xsl:text>az_code=</xsl:text>
<xsl:value-of select="/input/container/identity/entry[@type='oauth']/oauth-id[@type='access_request']/code"/>
<xsl:text>&az_code_ttl=</xsl:text>
<xsl:value-of select="/input/container//OAuthSupportedClient/au-code-lifetime"/>
</xsl:variable>
<xsl:message dp:priority="info"><xsl:value-of select="$url-query"/></xsl:message>
<!-- in reality, we should check for the return code to make sure the cache is actually stored -->
<xsl:variable name="message-response">
<dp:url-open target="{$url-query}"
response="responsecode-ignore">
</dp:url-open>
</xsl:variable>
</xsl:when>
</xsl:choose>
</xsl:when> <!-- End of access_request -->
(次頁へ続く)
外部リポジトリーの利用 (7/11)
revoke_addprocess.xsl (続き)
<xsl:when test="/input/operation = 'check_revocation_request'">
<xsl:variable name="url-query">
<xsl:value-of select="$cache-server-url"/>
<xsl:text>/check-revoke?client_id=</xsl:text>
<xsl:value-of select="/input/verified-token/client_id"/>
<xsl:text>&resource_owner=</xsl:text>
<xsl:value-of select="/input/verified-token/resource_owner"/>
<xsl:text>&token_type=</xsl:text>
<xsl:value-of select="/input/operation/@token-type"/>
<xsl:text>&token=</xsl:text>
<xsl:value-of select="/input/token"/>
<!-- in theory, user has the created date of the token, and they can write
more complex logic to only revoke those access created before resource owner revoke the client -->
</xsl:variable>
<xsl:message dp:priority="info"><xsl:value-of select="$url-query"/></xsl:message>
<!-- in reality, we should check for the return code to make sure the cache is actually stored -->
<xsl:variable name="message-response">
<dp:url-open target="{$url-query}"
response="responsecode-ignore">
</dp:url-open>
</xsl:variable>
<xsl:if test="$message-response/url-open/headers/header[@name='X-DP-Revoked'] = 'true'">
<result><revoked>revoked by checking external storage</revoked></result>
</xsl:if>
</xsl:when> <!-- End of check_revocation_request -->
<xsl:when test="/input/operation = 'preapproved_check'">
<result><approved>yes</approved></result>
</xsl:when>
</xsl:choose>
check_revocation_request処理の
カスタマイズ
© 2016 IBM Corporation 124
外部リポジトリーの利用 (8/11)
確認結果
アクセス・トークン発行
$ curl -i -k https://192.168.10.1:5070/oauth/token -d
"grant_type=authorization_code&code=AAIZI878LONO9aeC1x-
qpffWpMsoJdsC_ud4-gwIZLs2H4MxwZAPtcHy_WEzE48V80jjLgB_JqMAZdp2HV6a1iga8QyMAnttf1cXpR 6Abag2_AwBNGK6sSDzci9GgCzqb2A&redirect_uri=https://localhost" --user OAuthClient01:passw0rd
HTTP/1.1 200 OK
X-Backside-Transport: FAIL FAIL Connection: Keep-Alive
Transfer-Encoding: chunked Content-Type: application/json
Cache-Control: private, no-store, no-cache, must-revalidate Pragma: no-cache
{ "token_type":"bearer",
"access_token":"AAENT0F1dGhDbGllbnQwMcQE_HPxFxePnP8gVK8vtj23SUwuT xdavsNvMFTbvPK5tHRla6ROlxsb7dC_oR4UbhccQh7BKzPFrbNlaEuPOwSrr0l5fn wkdv6DderAJ30Ul87YOlG_sFDGBAzNRb7gdg", "expires_in":3600,
"scope":"/getAccountInfo /getCustomerInfo",
"refresh_token":"AAFbzncgpHbYu_y4zqQ3tJ_OfArYv9H_ahJhLMx_zGVgGKi1 zQNe3fJwxM5YhTDsrE0ghG8eb98qQvuhr8sWSQkgC8_Wt5yiMdoRlpUi6PA9IBUm6 ZXrq-pn9oR1nUEf_Us" }
>node --harmony cache-svr.js
cache server running on, , port 7088.
receive request,
/check-revoke?client_id=OAuthClient01&resource_owner=U SER01&tok
en_type=az-code&token=AAIZI878LONO9aeC1x-qpffWpMsoJdsC_ud4-gwIZLs2H4MxwZAPtcHy_W
EzE48V80jjLgB_JqMAZdp2HV6a1iga8QyMAnttf1cXpR6Ab ag2_AwBNGK6sSDzci9GgCzqb2A, at Th
u Mar 31 2016 08:10:28 GMT+0900 (東京 (標準時)) check revocation
not revoked
receive request,
/client- revoke?az_code=AAIZI878LONO9aeC1x-qpffWpMsoJdsC_ud4-gwI
ZLs2H4MxwZAPtcHy_WEzE48V80jjLgB_JqMAZdp2HV6a1ig a8QyMAnttf1cXpR6Abag2_AwBNGK6sSDz
ci9GgCzqb2A&az_code_ttl=300, at Thu Mar 31 2016 08:10:28 GMT+0900 (東京 (標準時)
)
cache client revoke info for at undefined and rt undefined
cURL 外部リポジトリー (Node.js)
アクセス・トークン発行時に、外部 リポジトリーに対してアクセス・
トークンの失効チェックを行う
外部リポジトリーの利用 (9/11)
確認結果 (続き)
アクセス・トークン失効
$ curl -i -k https://192.168.10.1:5070/oauth/token -d
"grant_type=urn:ibm:datapower:client:revoke&access_token=AAENT0F1 dGhDbGllbnQwMcQE_HPxFxePnP8gVK8vtj23SUwuTxdavsNvMFTbvPK5tHRla6ROl xsb7dC_oR4UbhccQh7BKzPFrbNlaEuPOwSrr0l5fnwkdv6DderAJ30Ul87YOlG_sF DGBAzNRb7gdg" --user OAuthClient01:passw0rd
HTTP/1.1 200 OK
X-Backside-Transport: FAIL FAIL Connection: Keep-Alive
Transfer-Encoding: chunked Content-Type: application/json
Cache-Control: private, no-store, no-cache, must-revalidate Pragma: no-cache
{ "status":"success" }
receive request,
/client-revoke?access_token=AAENT0F1dGhDbGllbnQwMcQE_HP xFxePnP8
gVK8vtj23SUwuTxdavsNvMFTbvPK5tHRla6ROlxsb7dC_oR 4UbhccQh7BKzPFrbNlaEuPOwSrr0l5fnw
kdv6DderAJ30Ul87YOlG_sFDGBAzNRb7gdg&access_toke n_ttl=3600, at Thu Mar 31 2016 08
:12:29 GMT+0900 (東京 (標準時)) cache client revoke info for at
AAENT0F1dGhDbGllbnQwMcQE_HPxFxePnP8gVK8vtj23SUw u
TxdavsNvMFTbvPK5tHRla6ROlxsb7dC_oR4UbhccQh7BKzP FrbNlaEuPOwSrr0l5fnwkdv6DderAJ30U
l87YOlG_sFDGBAzNRb7gdg and rt undefined
cURL 外部リポジトリー (Node.js)
IDGはアクセス・トークン失効要
求を受けて、外部リポジトリーに
失効情報を連携
© 2016 IBM Corporation 126
外部リポジトリーの利用 (10/11)
確認結果 (続き)
アクセス・トークン検査
$ curl -i -k https://192.168.10.1:5070/oauth/token -d
"grant_type=urn:ibm:datapower:validate&access_token=AAENT0F1dGhDb GllbnQwMcQE_HPxFxePnP8gVK8vtj23SUwuTxdavsNvMFTbvPK5tHRla6ROlxsb7d C_oR4UbhccQh7BKzPFrbNlaEuPOwSrr0l5fnwkdv6DderAJ30Ul87YOlG_sFDGBAz NRb7gdg" --user OAuthClient01:passw0rd
HTTP/1.1 200 OK
X-Backside-Transport: FAIL FAIL Connection: Keep-Alive
Transfer-Encoding: chunked Content-Type: application/json
Cache-Control: private, no-store, no-cache, must-revalidate Pragma: no-cache
{ "valid":false }
receive request,
/check-revoke?client_id=OAuthClient01&resource_owner=U SER01&tok
en_type=access_token&token=AAENT0F1dGhDbGllbnQw McQE_HPxFxePnP8gVK8vtj23SUwuTxdav
sNvMFTbvPK5tHRla6ROlxsb7dC_oR4UbhccQh7BKzPFrbNl aEuPOwSrr0l5fnwkdv6DderAJ30Ul87YO
lG_sFDGBAzNRb7gdg, at Thu Mar 31 2016 08:13:41 GMT+0900 (東京 (標準時))
check revocation revoked by client
cURL 外部リポジトリー (Node.js)
IDGはアクセス・トークン検査要
求を受けて、外部リポジトリーに
失効情報を確認
外部リポジトリーの利用 (11/11)
確認結果 (続き)
失効させたアクセス・トークンによるリソース・アクセス
$ curl -i -k https://192.168.10.1:5070/getCustomerInfo -H
"Authorization:Bearer
AAENT0F1dGhDbGllbnQwMcQE_HPxFxePnP8gVK8vtj23SUwuTxdavsNvMFTbvPK5t HRla6ROlxsb7dC_oR4UbhccQh7BKzPFrbNlaEuPOwSrr0l5fnwkdv6DderAJ30Ul8 7YOlG_sFDGBAzNRb7gdg"
HTTP/1.1 500 Error Content-Type: text/html
X-Backside-Transport: FAIL FAIL Connection: close
<!DOCTYPE HTML PUBLIC "-//W3C/DTD HTML 4.0 Transitional//EN">
<!--Licensed Materials - Property of IBM IBM WebSphere DataPower Appliances
Copyright IBM Corporation 2013. All Rights Reserved.
US Government Users Restricted Rights - Use, duplication or disclosure
restricted by GSA ADP Schedule Contract with IBM Corp.
-->
<html>
<title>Connectivity Error</title>
<body>
<h1>Web Application Gateway Error</h1><P/>
<h2><font color="red">Gateway detected an error during processing of service request.</font></h2><P/>
receive request,
/check-revoke?client_id=OAuthClient01&resource_owner=U SER01&tok
en_type=access_token&token=AAENT0F1dGhDbGllbnQw McQE_HPxFxePnP8gVK8vtj23SUwuTxdav
sNvMFTbvPK5tHRla6ROlxsb7dC_oR4UbhccQh7BKzPFrbNl aEuPOwSrr0l5fnwkdv6DderAJ30Ul87YO
lG_sFDGBAzNRb7gdg, at Thu Mar 31 2016 08:14:45 GMT+0900 (東京 (標準時))
check revocation revoked by client
cURL 外部リポジトリー (Node.js)
IDGはリソース・アクセス時に
外部リポジトリーに対して失効
チェックを行う
© 2016 IBM Corporation 128
外部リポジトリー利用時の考慮点
外部リポジトリー側で以下の検討が必要
データベースの性能 (トークンのレコード件数、パフォーマンス など)
冗長化
参考資料
IBM developerWorks
Implementing OAuth on IBM WebSphere DataPower Appliances
http://www.ibm.com/developerworks/websphere/library/techarticles/12 08_rasmussen/1208_rasmussen.html
Knowledge Center
IBM DataPower Gateway 7.2.0