D イメージ・ギャラリの作成
このチュートリアルでは、拡張的な例として、イメージを格納および取得するためのイメージ・ギャラリ・サービスの構築を説明します。このチュートリアルでは、Oracle Application Expressを使用します。
トピック:
関連項目:
このチュートリアルを行うには、「Oracle REST Data Servicesアプリケーションの開発」で取り上げた概念と技術をよく理解している必要があります。
D.1 はじめに
この項では、APIエントリ・ポイントに関するベスト・プラクティスに加え、この例で使用するいくつかの一般的な規則についても説明します。
トピック:
D.1.1 URIについて
この例全体にわたって、URIおよびURIテンプレートは、ホスト名、コンテキスト・ルートおよびワークスペースのパス接頭辞を省略した形で表記しています。次に例を示します。
gallery/images/
WebブラウザでこのURIにアクセスするには、次の形式でURIを使用します。
https://<host>:<port>/ords/<workspace>/gallery/images/
説明:
-
<host>
は、Oracle REST Data Servicesが実行されるホストです。 -
<port>
は、Oracle REST Data Servicesがリスニング中のポートです。 -
/ords
は、Oracle REST Data Servicesがデプロイされるコンテキスト・ルートです。 -
/<workspace>/
は、RESTfulサービスが定義されるOracle Application Expressワークスペースのワークスペース・パス接頭辞です。
D.1.2 ブラウザのサポートについて
この例では、HTML5および関連する仕様で定義されている多くの最新機能を使用しています。Mozilla FirefoxおよびGoogle Chromeでのみテストされています。Microsoft Internet Explorerまたはスマートフォン/タブレットのWebブラウザではテストされていません。この例では、Mozilla FirefoxまたはGoogle Chromeのいずれかの最新バージョンを使用してください。
D.3 ギャラリRESTfulサービス・モジュールの作成
ギャラリRESTfulサービス・モジュールを作成するには、次のステップを実行します。
-
「SQLワークショップ」に移動し、「RESTfulサービス」に移動します。
-
右側の「作成」をクリックし、次の情報を入力します。
-
名前:
gallery.example
-
URI接頭辞:
gallery/
-
URIテンプレート:
images/
-
メソッド:
POST
-
ソース: 次のように入力するかコピーして貼り付けます。
declare image_id integer; begin insert into gallery (title,content_type,image) values (:title,:content_type,:body) returning id into image_id; :status := 201; :location := image_id; end;
-
-
「モジュールの作成」をクリックします
-
images/
の下のPOST
ハンドラをクリックします。 -
「セキュア・アクセスが必要」で、
「いいえ」
を選択します。 -
「パラメータの作成」をクリックし、次にように入力します。
-
名前:
Slug
-
バインド変数名:
title
-
-
「作成」をクリックします。
-
右下の「パラメータの作成」をクリックし、次の情報を入力します。
-
名前:
X-APEX-FORWARD
-
バインド変数名:
location
-
アクセス方法:
OUT
-
-
「作成」をクリックします。
-
右下の「パラメータの作成」をクリックし、次の情報を入力します。
-
名前:
X-APEX-STATUS-CODE
-
バインド変数名:
status
-
アクセス方法:
OUT
-
パラメータ・タイプ:
Integer
-
-
「作成」をクリックします。
この時点で、新規イメージを格納できる単一のサービスを持つモジュールが作成できました。次に、格納されているイメージの一覧を表示するサービスを追加します。
-
「SQLワークショップ」に移動し、「RESTfulサービス」に移動します。
-
gallery.example
という名前のモジュールをクリックします。 -
images/
の下の「ハンドラの作成」をクリックし、次の情報を入力します。-
メソッド:
GET
-
ソース・タイプ:
Feed
-
セキュア・アクセスが必要:
No
-
ソース: 次のように入力するかコピーして貼り付けます。
select id,title,content_type from gallery order by id desc
-
-
「作成」をクリックします。
この時点で、イメージを格納およびリストするサービスが作成できました。次に、個別のイメージを表示するサービスを追加します。
-
「SQLワークショップ」に移動し、「RESTfulサービス」に移動します。
-
gallery.example
という名前のモジュールをクリックします。 -
gallery.exampleの下の「テンプレートの作成」をクリックし、次の情報を入力します。
-
URIテンプレート:
images/{id}
-
-
「作成」をクリックします。
-
images/{id}の下の「ハンドラの作成」をクリックし、次の情報を入力します。
-
メソッド:
GET
-
ソース・タイプ:
Media Resource
-
セキュア・アクセスが必要:
No
-
ソース: 次のように入力するかコピーして貼り付けます。
select content_type, image from gallery where id = :id
-
-
「作成」をクリックします。
D.4 ギャラリRESTfulサービスの試用
ギャラリRESTfulサービスを試用するには、次のステップを実行します。
ユーザーがギャラリにイメージを追加および表示できるOracle Application Expressアプリケーションを作成するには、「ギャラリ・アプリケーションの作成」を参照してください。
D.7 ギャラリRESTfulサービスの保護
イメージ・アップロード・サービスへのパブリック・アクセスを許可するのは賢明ではなく、ギャラリ内のイメージへのパブリック・アクセスを許可するのもまた理想的なことではありません。そのため、RESTfulサービスへのアクセスを保護する必要があります。
RESTfulサービスは、2種類の認証をサポートしています。
-
ファースト・パーティ認証。Application Expressアプリケーションが簡単に保護されたRESTfulサービスを消費できるように、RESTfulサービスを作成したパーティによって使用されることを意図した認証です。アプリケーションはRESTfulサービスとともに配置する、つまり、同じOracle Application Expressワークスペースに配置する必要があります。アプリケーションは、標準のOracle Application Express認証を使用する必要があります。
-
サード・パーティ認証。これは、RESTfulサービスを作成したパーティとは関連しない、サード・パーティ・アプリケーションによって使用されることを意図した認証です。サード・パーティ認証は、OAuth 2.0プロトコルを利用しています。
トピック:
D.7.1 RESTfulサービスの保護
RESTfulサービスを保護するには、次のステップを実行します。
-
「SQLワークショップ」に移動し、「RESTfulサービス」に移動します。
-
「タスク」というラベルのセクションで、RESTfulサービスの権限をクリックします。
-
「作成」をクリックし、次のように入力します。
-
名前:
example.gallery
-
ラベル:
Gallery Access
-
割当済グループ:
RESTful Services
-
説明:
ギャラリ内イメージの表示およびポスト
-
保護されたモジュール:
gallery.example
-
-
「作成」をクリックします。
今制限したRESTfulサービスへのアクセスを確認するには、次のステップを実行します。
-
「SQLワークショップ」に移動し、「RESTfulサービス」に移動します。
-
gallery.example
という名前のモジュールをクリックします。 -
images/
の下のGET
ハンドラをクリックします。 -
「テスト」をクリックします。
次の形式のURIがブラウザに表示されるはずです。
https://<host>:<port>/ords/resteasy/gallery/images
エラー・メッセージとともにエラー・ページが表示されるはずです。
401 Unauthorized.
関連項目:
適切な資格証明が提供されないかぎり保護されたRESTfulサービスにはアクセスできないので、これは予想どおりの結果です。リクエストに必要な資格証明を追加するには、「ファースト・パーティ認証を使用するためのアプリケーションの変更」を参照してください。
D.7.2 ファースト・パーティ認証を使用するためのアプリケーションの変更
ファースト・パーティ認証はCookieおよびApplication Expressアプリケーションによって確立されたユーザー・セッションを利用しますが、Oracle REST Data Servicesでは、Cookieの検証を可能にするために追加の情報を必要とします。アプリケーションIDと現在のセッションIDを知る必要があります。この情報は、Application Expressアプリケーションが常に把握しているもので、RESTfulサービスに送信される各リクエストにカスタムのHTTPヘッダーApex-Session
を追加することで、RESTfulサービスに対して行われるリクエストに含める必要があります。アプリケーションIDおよびセッションIDは、カンマによって各々が区切られ、ヘッダーの値として送信されます。次に例を示します。
GET /ords/resteasy/gallery/images/ Host: server.example.com Apex-Session: 102,6028968452563
場合によって、HTTPリクエストにカスタム・ヘッダーを含められないことがあります。たとえば、<img>
タグを使用したHTMLページ内でイメージを表示する場合などで、このような場合には別の方法を使用します。アプリケーションIDおよびセッションIDをカンマで区切り、_apex_session
という名前の問合せパラメータとしてリクエストURIに追加します。次に例を示します。
<img src="graphics/101?_apex_session=102,6028968452563">
この方法は、カスタム・ヘッダーが使用できない場合にのみ使用することに注意してください。それ以外の場合は、セッションIDをURIに含めることで、誤って保存されたり公開されたりするリスクが増加するため、この方法はお薦めしません。
各リクエストにファースト・パーティの認証情報を追加するようにアプリケーションを変更するには、次のステップを実行します。
-
Application Builderに移動します。
-
イメージ・ギャラリ・アプリケーションの横にある「編集」ボタンをクリックします。
-
「ホーム」
という名前の最初のページをクリックします。 -
「ページ」の下で、編集アイコンをクリックし、「JavaScript」タブをクリックします。
-
関数およびグローバル変数の宣言フィールドの先頭に次を追加します。
function setApexSession(pathOrXhr) { var appId = $v('pFlowId'); var sessionId = $v('pInstance'); var apexSession = appId + ',' + sessionId; if ( typeof pathOrXhr === 'string' ) { var path = pathOrXhr; if ( path.indexOf('?') == -1 ) { path = path + '?_apex_session=' + apexSession; } else { path = path + '&_apex_session=' + apexSession; } return path; } else { var xhr = pathOrXhr; xhr.setRequestHeader('Apex-Session',apexSession); return xhr; } }
-
これは、
setApexSession()
という名前のJavaScript関数を定義し、この関数はXMLHttpRequest
オブジェクトまたはパスを含む文字列にファースト・パーティの認証情報を追加します。次に、適切なときにこの関数を呼び出すように既存のJavaScriptコードを変更する必要があります。
-
xhr.open('POST',url,true);
という行の後に、次の行を追加します。setApexSession(xhr);
-
xhr.open('GET', gallery_url)
という行の後に、次の行を追加します。setApexSession(xhr);
-
var uri = item.uri['$ref'];
という行を次のように変更します。var uri = setApexSession(item.uri['$ref']);
-
「変更の適用」をクリックします。
-
前と同じようにアプリケーションを実行します。今度は、必要な認証情報をRESTfulサービスに提供しているので、動作するはずです。
D.8 サード・パーティ・アプリケーションからのRESTfulサービスへのアクセス
サード・パーティがギャラリRESTfulサービスを消費および使用する場合、サード・パーティ・アプリケーションを登録してOAuth 2.0の資格証明を取得する必要があり、その後、それをインタラクティブなプロセスを開始するために使用でき、ユーザーにかわってRESTfulサービスにアクセスするサード・パーティ・アプリケーションに権限を付与できます。
アプリケーションが登録されると、アクセス・トークンを取得できます。アクセス・トークンは、保護されたRESTfulサービスへの各リクエストに指定する必要があります。Oracle REST Data Servicesは、RESTfulサービスへのアクセスを許可する前に、そのアクセス・トークンを検証します。
OAuth 2.0では、アプリケーションがアクセス・トークンを取得するために使用できる、多数の異なるプロトコル・フローが定義されています。Oracle REST Data Servicesでは、これらのプロトコル・フローのうち次の2つがサポートされています。
-
認可コード。サード・パーティ・アプリケーションがそのクライアントの資格証明をセキュアに保持できる場合、たとえば、サード・パーティのWebサイトが適切に保護されている場合などにこのフローが使用されます。
-
暗黙の権限付与サード・パーティ・アプリケーションがその資格証明を機密にしておくことを保証できない場合、たとえば、JavaScriptベースのブラウザ・アプリケーションまたはネイティブのスマートフォン・アプリケーションなどでこのフローが使用されます。
最初のステップは、サード・パーティ・アプリケーションの登録です。このデモを行うため、サード・パーティの開発者を表すユーザーを作成し、このユーザーを使用してアプリケーションを登録します。
この後のステップでは、RESTEASY
ワークスペースのユーザー・リポジトリにユーザーを作成し、関連する処理を実行します。
ノート:
Oracle REST Data Servicesでは、ワークスペースのユーザー・リポジトリに定義されたユーザーの認証に加え、WebLogic Serverからアクセス可能な任意のユーザー・リポジトリに対する認証も可能です。詳細は、WebLogicサーバーに対する認証を参照してください。
トピック:
D.8.1 サード・パーティの開発者ユーザーの作成
サード・パーティの開発者ユーザー(RESTfulサービスにアクセスするアプリケーションを登録するサード・パーティの開発者のユーザー・アカウント)を作成するには、次のステップを実行します。
D.8.3 アクセス・トークンの取得
アクセス・トークンを取得するには、アクセス承認のプロンプトをユーザーに表示する必要があります。承認プロセスを開始するには、次のURIを使用してユーザーを承認ページに誘導します。
https://server:port/ords/resteasy/oauth2/auth?response_type=token&\ client_id=CLIENT_IDENTIFIER&\ state=STATE
説明:
-
CLIENT_IDENTIFIER
は、登録時にアプリケーションに割り当てられたクライアント識別子です。 -
STATE
は、クロス・サイト・リクエスト・フォージェリ(CSRF)攻撃を防止するために使用される、アプリケーションによって生成された固有の値です。
Oracle REST Data ServicesのOAuth 2.0実装では、次の点に注意してください。
-
OAuth 2.0仕様では、前述のリクエストでは次の2つのオプション・パラメータが指定できます。
-
redirect_uri
: ユーザーがアクセスを承認/拒否した後で、認可サーバーをリダイレクトする場所を指定します。 -
scope
: クライアントがアクセスしようとするRESTfulサービスの権限を指定します。
Oracle REST Data Servicesでは、これらのパラメータのどちらもサポートしていません。どちらの値もクライアントの登録時に指定されるので、ここでそれを繰り返すのは冗長になるためです。これらのパラメータに指定された値は無視されます。
-
-
OAuth 2.0仕様では
state
パラメータの使用を推奨していますが、Oracle REST Data Servicesでは、CSRF攻撃の防止に役立つという重要性から、このパラメータの使用を必須としています。 -
レスポンス・タイプもアプリケーションの登録時に指定されるため、
response_type
パラメータも冗長ですが、OAuth 2.0仕様でこのパラメータは常に必須と明言されているため、含める必要があります。response_type
の値が登録時のレスポンス・タイプと異なる場合はエラーになります。
ブラウザで前述のURIにアクセスすると、ユーザーはサインオンするように促され、その後、アプリケーションのアクセス・リクエストを確認し、アクセスを承認するか拒否するか選択するように求められます。
ユーザーがリクエストを承認した場合、ブラウザは登録されたリダイレクトURIにリダイレクトされ、アクセス・トークンはURIの一部分としてエンコードされます。
https://example.org/#token_type=bearer&\ access_token=ACCESS_TOKEN&\ expires_in=TOKEN_LIFETIME&\ state=STATE
説明:
-
example.org
は、説明目的でのみ使用されます。実際のアプリケーションでは、example.org
はアクセスをリクエストするサード・パーティ・アプリケーションのURLに置き換えられます。 -
ACCESS_TOKEN
は、現在のユーザー・セッションに割り当てられた一意の推測できないアクセス・トークンで、RESTfulサービスに対する後続のリクエストでこれを指定する必要があります。 -
TOKEN_LIFETIME
は、アクセス・トークンが有効である秒数です。 -
STATE
は、認可フローの開始時にアプリケーションによって提供される一意の値です。戻されたstate
の値が初期のstate
の値と一致しない場合、それはエラー状態であり、攻撃者がCSRF攻撃により認可プロセスを破壊しようとしている可能性があるため、アクセス・トークンは使用しないでください。
ノート:
生成されたすべてのアクセス・トークンのデフォルトのOAuthアクセス・トークン期間(存続期間)を変更できます。これを実現するには、次のようにして、defaults.xml
構成ファイルに、OAuthアクセス・トークン期間を秒単位で指定するsecurity.oauth.tokenLifetime
エントリを追加します。
<entry key="security.oauth.tokenLifetime">600</entry>
ユーザーがリクエストを拒否するか、またはユーザーがRESTfulサービスへのアクセスを許可されていない場合、ブラウザは登録されたリダイレクトURIにリダイレクトされ、エラー・メッセージがURIの一部分にエンコードされます。
https://example.org/#error=access_denied&state=STATE
説明:
-
error=access_denied
は、ユーザーがRESTfulサービスへのアクセスを許可されていない、またはアプリケーションのアクセスを承認しないことを選択したことをクライアントに通知します。 -
STATE
は、認可フローの開始時にアプリケーションによって提供される一意の値です。戻されたstate
の値が初期のstate
の値と一致しない場合、それはエラー状態であり、クライアントはそのレスポンスを無視してください。これは、攻撃者がCSRF攻撃により認可プロセスを破壊しようとしている可能性があります。
D.8.4 アクセス・トークンの使用
アプリケーションがアクセス・トークンを取得した後は、保護されたRESTfulサービスに対する各リクエストにそのアクセス・トークンを含める必要があります。これを行うには、Authorization
ヘッダーを次の構文でHTTPリクエストに追加します。
Authorization: Bearer ACCESS_TOKEN
説明:
-
ACCESS_TOKEN
は、アクセス・トークンの値です。
たとえば、JavaScriptベースのブラウザ・アプリケーションが次のようにギャラリ・サービスを呼び出すことがあります。
var accessToken = ... /* initialize with the value of the access token */ var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://server:port/ords/resteasy/gallery/images/',true); /* Add the Access Token to the request */ xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken); xhr.onload = function(e) { /* logic to process the returned JSON document */ ... }; xhr.send();
この例は、XMLHttpRequest.setRequestHeader(name,value)
関数を使用し、Authorization
ヘッダーをHTTPリクエストに追加しています。アクセス・トークンが有効ならば、サーバーはギャラリ内のイメージのリストを表示するJSONドキュメントを戻します。
D.8.5 ブラウザのオリジンについて
Webブラウザの主要なセキュリティ概念の1つに同一生成元ポリシーがあり、これは、同じWebサイト(オリジン)から生成されるページ上で実行中のスクリプトには制限なしで互いのデータにアクセスすることを許可し、他のWebサイトから生成されるデータにはアクセスさせないというものです。
オリジンは、Webサイトのプロトコル、ホスト名およびポートによって定義されます。たとえば、https://example.com
は1つのオリジンで、https://another.example.com
はホスト名が異なるため異なるオリジンです。同様に、http://example.com
はプロトコルが異なるためhttps://example.com
とは異なるオリジンです。最後に、http://example.com
はポートが異なるためhttp://example.com:8080
とは異なるオリジンです。
たとえば、ギャラリRESTfulサービスの場合、サード・パーティのクライアントは次の場所にあります。
https://thirdparty.com/gallery.html
そして、ギャラリRESTfulサービスは次の場所にあります。
https://example.com/ords/resteasy/gallery/images/
そこで、同一生成元ポリシーにより、https://thirdparty.com
オリジンのスクリプトは同じオリジンのデータにのみアクセス可能であり、https://example.com
は明らかに異なるオリジンであることから、gallery.html
の行うhttps://example.com/ords/resteasy/gallery/images/
へのXMLHttpRequest
は阻止されます。
https://example.com
の作成者がhttps://thirdparty.com
の作成者を信頼できない場合には、これは妥当なことです。しかし、作成者が互いに信頼するだけの理由がある場合には、同一生成元ポリシーは制限が大きすぎます。クロス・オリジン・リソース共有(CORS)と呼ばれるプロトコルにより、https://example.com
からブラウザにhttps://thirdparty.com
を信頼していることを通知する手段が提供されており、gallery.html
の行うhttps://example.com/ords/resteasy/gallery/images/
へのXMLHttpRequest
を許可するようにブラウザに指示できます。
D.8.6 クロス・オリジン・リソース共有のためのRESTfulサービスの構成
クロス・オリジン・リソース共有のRESTfulサービスを構成するには、次のステップを実行します。
- 「SQLワークショップ」に移動し、「RESTfulサービス」に移動します。
gallery.example
という名前のモジュールをクリックします。- 許可済オリジンに、RESTfulサービスへのアクセスが許可されるオリジンを入力します(複数オリジンはカンマで区切ります)。
- 「変更の適用」を押します。
D.8.7 認可コード・プロトコル・フローを使用したトークンの取得
他の項で、OAuth 2.0の暗黙のプロトコル・フローを使用したアクセス・トークンの取得方法を説明しました。この項では、認可コードのプロトコル・フローを使用して同じことをする方法を説明します。その手順は、認可コードとアクセス・トークンの交換を必要とするため、暗黙のプロトコル・フローよりも少しばかり複雑です。
この項では、cURLを使用してこの交換手順を模倣します。
トピック:
D.8.7.2 認可コードの取得
認可コード・プロトコル・フローの最初のステップは、認可コードを取得することです。認可コードは、アプリケーションのクライアント識別子およびクライアント・シークレットと一緒に提示された場合、アクセス・トークンと交換できる有効期限の短いトークンです。
アクセス・トークンを取得するには、アクセス承認のプロンプトをユーザーに表示する必要があります。承認プロセスを開始するには、次の形式のURIを使用してユーザーを承認ページに誘導します。
https://server:port/ords/resteasy/oauth2/auth?response_type=code&\ client_id=CLIENT_IDENTIFIER&\ state=STATE
説明:
-
CLIENT_IDENTIFIER
は、登録時にアプリケーションに割り当てられたクライアント識別子です。 -
STATE
は、クロス・サイト・リクエスト・フォージェリ(CSRF)攻撃を防止するために使用される、アプリケーションによって生成された固有の値です。
ユーザーがリクエストを承認した場合、ブラウザは登録されたリダイレクトURIにリダイレクトされ、アクセス・トークンはURIの問合せ文字列の一部分としてエンコードされます。
https://gallery.example.demo?code=AUTHORIZATION_CODE&state=STATE
説明:
-
AUTHORIZATION_CODE
は、認可コードの値です。 -
STATE
は、認可フローの開始時にアプリケーションによって提供される一意の値です。戻されたstate
の値が初期のstate
の値と一致しない場合、それはエラー状態であり、認可コードは使用しないでください。これは、攻撃者がCSRF攻撃により認可プロセスを破壊しようとしている可能性があります。登録されたリダイレクトURI
https://gallery.example.demo
が存在しないので、ブラウザはサーバーに「見つかりません」のエラーを報告しますが、URIにエンコードされた認可コードの値を見ることはできるので、この例の目的のためには問題ありません。「認可コードとアクセス・トークンの交換」で使用するため、code
パラメータの値をノートにとっておいてください。
D.8.7.3 認可コードとアクセス・トークンの交換
この項では、cURLを使用して認可コードとアクセス・トークンを交換します。認可コードを交換するため、アプリケーションでは、認可コードおよびそのクライアント識別子とクライアント・シークレットを提供し、Oracle REST Data ServicesのOAuth 2.0トークン・エンドへのHTTPリクエストを行う必要があります。資格証明が正しい場合は、Oracle REST Data Servicesによりアクセス・トークンを含むJSONドキュメントが戻されます。アプリケーションはサーバー側(クライアント識別子とクライアント・シークレットが安全に格納されている)から直接Oracle REST Data ServicesへのHTTPリクエストを行うことに注意してください。プロトコル・フローのこのステップではWebブラウザはまったく関与していません。
認可コードとアクセス・トークンを交換するには、次の形式でcURLコマンドを使用します。
curl -i -d "grant_type=authorization_code&code=AUTHORIZATION_CODE" \ --user CLIENT_IDENTIFER:CLIENT_SECRET \ https://server:port/ords/resteasy/oauth2/token
説明:
-
AUTHORIZATION_CODE
は、認可コードの値です(前の項のリダイレクトURIの問合せ文字列のcode
パラメータにエンコードされたものです)。 -
CLIENT_IDENTIFER
は、クライアント識別子の値です。 -
CLIENT_SECRET
は、クライアント・シークレットの値です。
cURLにより、前述のコマンドが次のようなHTTPリクエストに変換されます。
POST /ords/resteasy/oauth2/token HTTP/1.1 Authorization: Basic Q0xJRU5UX0lERU5USUZJRVI6Q0xJRU5UX1NFQ1JFVA== Host: server:port Accept: */* Content-Length: 59 Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=AUTHORIZATION_CODE
説明:
-
このリクエストは、OAuth 2.0のトークン・エンド
oauth2/token
へのHTTPのPOST
です。 -
Authorization
ヘッダーは、HTTPBASIC
認証プロトコルを使用し、アプリケーションのアイデンティティを示すためのクライアント識別子とクライアント・シークレットをエンコードします。 -
リクエストの
Content-Type
は、フォーム・データ(application/x-www-form-urlencoded
)であり、リクエストのコンテンツはOAuth 2.0トークン権限タイプおよびOAuth 2.0認可コード値を示すフォーム・データです。
前述のHTTPリクエストに対し、次のようなレスポンスが生成されます。
HTTP/1.1 200 OK ETag: "..." Content-Type: application/json { "access_token":"04tss-gM35uOeQzR_2ve4Q..", "token_type":"bearer", "expires_in":3600, "refresh_token":"UX4FVHhPFJl6GokvTXYw0A.." }
レスポンスは、リフレッシュ・トークンとともにアクセス・トークンを含むJSONドキュメントです。アプリケーションがアクセス・トークンを取得した後は、保護されたRESTfulサービスに対する各リクエストにそのアクセス・トークンを含める必要があります。これを行うには、Authorization
ヘッダーを次の構文でHTTPリクエストに追加します。
Authorization: Bearer ACCESS_TOKEN
関連トピック
D.8.7.4 OAuth 2.0セッションの継続時間の延長
OAuth 2.0セッションの存続期間を延長するため、リフレッシュ・トークンを新規の有効期限を持つ新規のアクセス・トークンと交換できます。リフレッシュ・トークンは認可コードのプロトコル・フローでのみ発行されることに注意してください。
アプリケーションは、認可コードとアクセス・トークンの交換に使用したものと同様のリクエストを行います。アクセス・トークンのためのリフレッシュ・トークンを交換するには、次の形式でcURLコマンドを使用します。
curl -i -d "grant_type=refresh_token&refresh_token=REFRESH_TOKEN" \ --user CLIENT_IDENTIFER:CLIENT_SECRET \ https://server:port/ords/resteasy/oauth2/token
説明:
-
REFRESH_TOKEN
は、アクセス・トークンが最初に発行されたときに戻されたリフレッシュ・トークンの値です。 -
CLIENT_IDENTIFER
は、クライアント識別子の値です。 -
CLIENT_SECRET
は、クライアント・シークレットの値です。
cURLにより、前述のコマンドが次のようなHTTPリクエストに変換されます。
POST /ords/resteasy/oauth2/token HTTP/1.1 Authorization: Basic Q0xJRU5UX0lERU5USUZJRVI6Q0xJRU5UX1NFQ1JFVA== Host: server:port Accept: */* Content-Length: 53 Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=REFRESH_TOKEN
説明:
-
このリクエストは、OAuth 2.0のトークン・エンド
oauth2/token
へのHTTPのPOST
です。 -
Authorization
ヘッダーは、HTTPBASIC
認証プロトコルを使用し、アプリケーションのアイデンティティを示すためのクライアント識別子とクライアント・シークレットをエンコードします。 -
リクエストの
Content-Type
は、フォーム・データ(application/x-www-form-urlencoded
)であり、リクエストのコンテンツはOAuth 2.0トークン権限タイプおよびリフレッシュ・トークン値を示すフォーム・データです。
前述のHTTPリクエストに対し、次のようなレスポンスが生成されます。
HTTP/1.1 200 OK ETag: "..." Content-Type: application/json { "access_token":"hECH_Fc7os2KtXT4pDfkzw..", "token_type":"bearer", "expires_in":3600, "refresh_token":"-7OBQKc_gUQG93ZHCi08Hg.." }
レスポンスは、新規のリフレッシュ・トークンとともに新規のアクセス・トークンを含むJSONドキュメントです。既存のアクセス・トークンおよびリフレッシュ・トークンは無効になり、古いアクセス・トークンを使用してサービスにアクセスしようとすると失敗します。
D.8.8 アクセス・トークンの保護について
OAuth 2.0では、アクセス・トークンは保護されたサービスにアクセスするために提供する必要のある唯一の資格証明です。このため、アクセス・トークンをセキュアに保持することは重要です。トークンのセキュアな保持を促進するため、次のガイドラインに従ってください。
-
すべての保護されたRESTfulサービスにHTTPSを使用することを強くお薦めします。これにより、安全でないチャネル上の盗聴により攻撃者がアクセス・トークンを盗むことができるスヌーピング攻撃を防ぎます。また、攻撃者によるリクエストのペイロードに存在する機密データの表示を防ぐことができます。
-
クライアント・アプリケーションが、信頼できない他のアプリケーションまたはスクリプトとともにブラウザのオリジンに配置されていないことを確認してください。たとえば、アリスというユーザーが次の場所でホストされているクライアント・アプリケーションを持っているとします。
https://sharedhosting.com/alice/application
別のユーザー(たとえばフレッド)もまた、次のように同じオリジンに彼のアプリケーションをホストできる場合、
https://sharedhosting.com/fred/trouble
同じオリジン
https://sharedhost.com
を共有しているため、ブラウザではどちらのアプリケーションについても相手のデータにアクセスすることを防ぐことはできず、/alice/application
が取得したアクセス・トークンを盗むことは、/fred/trouble
には容易になります。このようなシナリオを防ぐために、アリスのアプリケーションは、たとえば、自身のオリジンにデプロイする必要があります。
https://alice.sharedhosting.com/application
または
https://application.alice.sharedhosting.com
または
https://aliceapp.com