REST サービスでの CORS のサポート
CORS (Cross-origin Resource Sharing) によりスクリプトを別のドメインで実行して Caché REST サービスにアクセスすることができます。通常、ブラウザは 1 つのドメインからスクリプトを実行している場合、同じドメインへの XMLHttpRequest の呼び出しを許可しますが、別のドメインへ呼び出される場合は許可しません。このブラウザ動作により、機密データを不正使用するおそれのある悪意のあるスクリプトの作成が制限されます。悪意のあるスクリプトにより、ユーザは与えられた許可を使用して別のドメインの情報にアクセスできますが、ユーザの知らない者が機密情報を他の用途に用いることもできます。こうしたセキュリティの問題を回避するため、通常ブラウザはこの種のクロスドメイン呼び出しを許可しません。
CORS を使用しない場合、REST サービスにアクセスするスクリプトを使用する Web ページは通常、REST サービスを提供するサーバと同じドメインにある必要があります。一部の環境では、スクリプトを使用する Web ページを REST サービス提供サーバとは異なるドメインに置くと便利です。CORS はこのような配置を可能にします。
以下ではブラウザが CORS で XMLHttpRequest を処理する方法を簡略化して説明します。
-
ドメイン DomOne にある Web ページのスクリプトにはドメイン DomTwo にある Caché REST サービスへの XMLHttpRequest が含まれます。XMLHttpRequest には CORS のカスタム・ヘッダがあります。
-
ユーザはこの Web ページを閲覧してスクリプトを実行します。Web ページを含むドメインとは異なるドメインへの XMLHttpRequest をユーザのブラウザは検出します。
-
ユーザのブラウザは Caché REST サービスへ特別な要求を送信します。これは XMLHttpRequest の HTTP 要求メソッドおよび元の Web ページのドメイン (この例では DomOne) を示します。
-
要求が許可されると、応答には要求された情報が含まれます。許可されない場合、CORS が要求を許可しなかったことを示すヘッダのみで応答は構成されます。
Caché では HTTP ヘッダを渡すことで CORS がサポートされ、REST サービスが CORS ヘッダを許可するかどうか構成できます。CORS 要求を許可する場合を定義するコードを記述する必要があります。例えば、信頼されたスクリプトのみを含むドメインを含むホワイトリストを提供することができます。Caché はドキュメント用に単純な既定の実装を提供しますが、任意の CORS 要求を許可します。機密データ向けにこの既定の実装を使用する CORS 処理を有効にしないでください。
CORS 要求を制御するコードを記述するには、%CSP.RESTOpens in a new tab サブクラスの OnHandleCorsRequest() メソッドをオーバーライドします。
この章には、以下のセクションが含まれます。
CORS 使用のための REST サービスの構成
REST サービスが UrlMap の route 要素の %CSP.RESTOpens in a new tab HandleCorsRequest パラメータおよび Cors 属性で CORS をサポートするかどうかを制御します。
%CSP.RESTOpens in a new tab サブクラスで定義されたすべての REST サービスの CORS ヘッダ処理を有効または無効にするには、HandleCorsRequest パラメータを "true" に設定して CORS 処理を有効にするか、既定の "false" に設定して CORS 処理を無効にします。
UrlMap の各 Route で個別に CORS ヘッダ処理を有効または無効にするには、HandleCorsRequest パラメータを "" (空の文字列) に設定し、Route 要素で Cors="true" を指定して CORS 処理を有効にし、また Route 要素で Cors="false" を指定して CORS 処理を無効にします。
%CSP.RESTOpens in a new tab サブクラスが REST 要求を当該 REST URL と一致する Route を含む 2 番目の %CSP.RESTOpens in a new tab サブクラスに転送する場合、一致する Route を含む %CSP.RESTOpens in a new tab サブクラスの HandleCorsRequest パラメータは CORS 処理の動作を制御します。
CORS ヘッダを有する受信 REST URL で CORS 処理が無効な場合、%CSP.RESTOpens in a new tab は受信要求を拒否します。
OnHandleCorsRequest メソッドのオーバーライド
OnHandleCorsRequest() メソッドの既定の実装ではフィルタ処理は実行されず、CORS ヘッダが外部サーバへ渡され、応答が返されるだけです。ドメインのホワイトリストにリストされた起源へのアクセスを制限する、または許可される要求メソッドの種類を制限することができます。これは %CSP.RESTOpens in a new tab サブクラスの OnHandleCorsRequest() メソッドをオーバーライドすることで行います。
UrlMap 中の Route 要素と一致するすべての URL 要求はクラス内で定義された単一の OnHandleCorsRequest() メソッドで処理します。異なる REST URL 要求に OnHandleCorsRequest() メソッドの異なる実装が必要な場合、Forward を使用して %CSP.RESTOpens in a new tab の異なるサブクラスへ要求を送信する必要があります。
OnHandleCorsRequest() メソッドを実装するには、CORS プロトコルの詳細に精通している必要があります。このセクションでは、既定の OnHandleCorsRequest() メソッドを実装する部分と起源、資格情報、ヘッダおよび要求メソッドを処理する行について確認します。
%CSP.REST.HandleDefaultCorsRequest() メソッドに由来する以下のコードでは起源を取得し、使用して応答ヘッダを設定します。この処理を行う一例として、起源をホワイトリストに対してテストし、それを使用して、ドメインが許可されている場合に応答ヘッダを設定します。許可されていない場合、応答ヘッダを空の文字列に設定できます。
#; Get the origin
Set tOrigin=$Get(%request.CgiEnvs("HTTP_ORIGIN"))
#; Allow requested origin
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Origin",tOrigin)
以下の行では認証ヘッダが含まれるように指定します。
#; Set allow credentials to be true
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Credentials","true")
以下の行では受信する要求からヘッダと要求メソッドを取得します。コードを追加してこれらのヘッダと要求メソッドが許可されているかテストします。許可されている場合、それらを使用して応答ヘッダを設定します。
#; Allow requested headers
Set tHeaders=$Get(%request.CgiEnvs("HTTP_ACCESS_CONTROL_REQUEST_HEADERS"))
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Headers",tHeaders)
#; Allow requested method
Set tMethod=$Get(%request.CgiEnvs("HTTP_ACCESS_CONTROL_REQUEST_METHOD"))
Do ..SetResponseHeaderIfEmpty("Access-Control-Allow-Method",tMethod)
%CSP.REST.HandleDefaultCorsRequest() メソッドはドキュメント用のみに単純な既定の実装を提供します。機密データ向けにこの既定の実装を使用する CORS 処理を有効にしないでください。