3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Oracle Database 12cからのHTTPSアクセスに必要な設定

Last updated at Posted at 2017-11-11

Oracle Application Container Cloudで作ったREST APIに対して、Oracle Databaseから PL/SQLでUTL_HTTPパッケージを使ってアクセスするプログラムを書いたとき、HTTPSでアクセスするための設定がいろいろ必要だったので、備忘録です。ちなみに、Windows上のOracle DBで試しました。

#dbms_network_acl_adminの設定
Oracle DBからHTTPSリクエストを発行する場合、dbms_network_acl_adminで接続先に対してポート443でアクセスするための設定を行う必要があります。dbms_network_acl_adminは、11gと12cでは設定が少し違います。

今回、12cR2の PDBからアクセスしてみたので、その手順で書きます。

dbms_network_acl_adminの設定は、SQL*PlusからSYSDBAでログインしてPDB上で実行します。

connect sys/Password as sysdba
ALTER SESSION SET CONTAINER = orclpdb;


declare
    host_name varchar2(100) := '{アクセス先のDNS名}';
begin
  dbms_network_acl_admin.append_host_ace (
      host       => host_name,
      lower_port => 443,
      upper_port => 443,
      ace        => xs$ace_type(privilege_list => xs$name_list('http'),
                                principal_name => '{DBユーザー名}',
                                principal_type => xs_acl.ptype_db));
  end;
/

declare
    host_name varchar2(100) := '{アクセス先のDNS名}';
begin
    dbms_network_acl_admin.append_host_ace (
      host       => host_name,
      lower_port => 443,
      upper_port => 443,
      ace        => xs$ace_type(privilege_list => xs$name_list('http_proxy'),
                                principal_name => '{DBユーザー名}',
                                principal_type => xs_acl.ptype_db));
  end;
/

#Oracle WalletにCA登録
Oracle DBから外部にHTTPSでアクセスするには、Oracle WalletにCA認証書を登録する必要があります。この手順は以下の記事を参考にさせていただきました。
http://cosol.jp/techdb/2015/12/https-using-utl-http-how-to-aviod-ora-29024.html

Windowsでは以下のようにやってみました。
###Oracle Walletの作成
orapki wallet createコマンドで、空のOracleウォレットを作成します。

set ORACLE_WALLET_PATH={Oracle Walletのディレクトリ}
set ORACLE_WALLET_PWD={Walletのパスワード}

call orapki wallet create -wallet %ORACLE_WALLET_PATH% -pwd %ORACLE_WALLET_PWD% -auto_login

###CA証明書の準備
テスト用に試したので、
http://curl.haxx.se/ca/cacert.pem
にアクセスして、ルートCA証明書cacert.pemをダウンロードしたものを使いました。
このままでは適切に Oracle Walletに組み込めないため、インポート可能な形式に変換します。
Windowsの場合、gawkをインストールして以下を実行します。

gawk " split_after == 1 { n++; split_after=0 } /-----END CERTIFICATE-----/ { split_after=1 } { print > \"cert\" n \".pem\" }" < cacert.pem

これにより多数のpemファイルが生成されます。
###CA証明書を追加
次に orapki wallet add -trusted_cert -cert コマンドでOracleウォレットにルートCA証明書を追加します。
バッチファイルで、たとえば以下を実行します。

for %%f in (*.pem) do (
  orapki wallet add -wallet %ORACLE_WALLET_PATH% -trusted_cert -cert %%f -pwd %ORACLE_WALLET_PWD%
  echo %%f
)

#PL/SQLからのHTTPSアクセス

PL/SQLでのSSLの有効化

PL/SQLでHTTPSアクセスするには、まず
UTL_HTTP.SET_WALLET('Oracle Walletのパス', 'Walletのパスワード') を行います。

実際にアクセスする

以下は、dbms_network_acl_adminに登録したDBユーザーから登録したアクセス先に対し、HTTPSでPUTメソッドを使ってJSONを送る例です。DBのキャラクタセットはAL32UTF8を使っています。

connect c##adm/test
ALTER SESSION SET CONTAINER = orclpdb;

DECLARE
    v_walletpath VARCHAR2(4000) := 'file:d:\app\test\wallet'; -- 「file:」を入れるのを忘れずに
    v_walletpwd VARCHAR2(100) := 'WalletPasswd123';

    v_req   UTL_HTTP.REQ;
    v_resp  UTL_HTTP.RESP;
    v_json  VARCHAR2(4000) := '{ "id" : "1234", "name" : "テスト"}';
    v_buf VARCHAR2(4000); 

BEGIN
   -- Walletを指定
   UTL_HTTP.SET_WALLET(v_walletpath, v_walletpwd); 

   -- HTTPリクエスト
   v_req := UTL_HTTP.BEGIN_REQUEST('https://{登録したホスト名}/cache/1234', 'PUT', UTL_HTTP.HTTP_VERSION_1_1);

    UTL_HTTP.SET_HEADER(v_req, 'Content-Type', 'application/json; charset=utf-8');
    UTL_HTTP.SET_HEADER(v_req, 'Content-Length', LENGTHB(v_json)); -- LENGTHBにする

    UTL_HTTP.WRITE_RAW(v_req, UTL_RAW.CAST_TO_RAW(v_json)); -- JSONは文字列ではなくRAWにすること
    
    -- レスポンスを取得
    v_resp := UTL_HTTP.GET_RESPONSE(v_req);
    DBMS_OUTPUT.PUT_LINE('Status Code: ' || TO_CHAR(v_resp.STATUS_CODE));
    DBMS_OUTPUT.PUT_LINE('Message: ' || v_resp.REASON_PHRASE);

    BEGIN
      LOOP
        UTL_HTTP.READ_LINE(v_resp, v_buf);
        DBMS_OUTPUT.PUT_LINE(v_buf);
      end LOOP;
      UTL_HTTP.END_RESPONSE(v_resp);
    EXCEPTION
      WHEN UTL_HTTP.END_OF_BODY 
      THEN
        UTL_HTTP.END_RESPONSE(v_resp);
    END;

END;
/
  • Walletのパスには「file:」を入れること。
  • Content-Lengthにセットする送信データのサイズは、LENGTH(文字数)ではなくLENGTHB(バイト数)を使うこと。あまりに久々にPL/SQL使ったので、忘れてて文字化けしました...。
  • あと、送信データはRAW型に変換してから送るようにします。

これを実行した後、以下のようにアクセスすると、登録したデータを取得できました。

SQL> SELECT UTL_HTTP.REQUEST('https://{ホスト名}/cache/1234') FROM DUAL;

UTL_HTTP.REQUEST('HTTPS://{ホスト名}/CACHE/
--------------------------------------------------------------------------------
{"id":"1234","name":"テスト"}
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?