2023年3月3日金曜日

Open ID ConnectまたはOAuth2による認証の応答を印刷する

Oracle APEXのアプリケーションの認証スキームとしてOpen ID Connectを使った際に、認証後のプロシージャとして以下のようなコードを書いています。

procedure post_auth is
begin
:G_DISPLAY_NAME := apex_json.get_varchar2('name');
end post_auth;
APEX側ではIdPからの応答であるJSON形式のメッセージをパースした状態(apex_json.parseを呼び出した状態)で、認証後のプロシージャを呼び出しています。そのため、IdPが応答としてどのようなメッセージを返すかが分かっていれば、apex_json.get_varchar2といったファンクションを呼び出すことでIdPから返された値を取得することができます。

IdPがどのような応答をするかはIdPに確認すべきことではあるのですが、とりあえず受信した応答をダンプするファンクションを作成してみました。

create or replace function dump_signon_response
return clob
as
k varchar2(32767);
v apex_json.t_value;
t apex_json.t_kind;
res clob := '';
begin
k := apex_json.g_values.first;
while k is not null loop
v := apex_json.get_value(k);
res := res || k || ' = ';
case v.kind
when apex_json.c_null then
res := res || '(NULL)';
when apex_json.c_true then
res := res || '(TRUE)';
when apex_json.c_false then
res := res || '(FALSE)';
when apex_json.c_number then
res := res || to_char(v.number_value);
when apex_json.c_varchar2 then
res := res || v.varchar2_value;
when apex_json.c_object then
res := res || '(OBJECT[' || apex_string.join(v.object_members, ':') || '])';
when apex_json.c_array then
res := res || '(ARRAY[' || to_number(v.number_value) || '])';
when apex_json.c_clob then
res := res || v.clob_value;
else
res := res || '(OTHER)';
end case;
res := res || apex_application.LF;
k := apex_json.g_values.next(k);
end loop;
return res;
end dump_signon_response;

アプリケーション・アイテムを作成し(以下の例ではG_USER_INFO)、認証後のプロシージャで値を設定します。

procedure post_auth is
begin
:G_USER_INFO := dump_signon_response;
end post_auth;

後は静的コンテンツのリージョンに以下のようにソースを記述すると、IdPの応答が画面に出力されます。

<pre>&G_USER_INFO.</pre>


以下のような表示になります。トークンなどは永続的なものではありませんが、センシティブな情報ではあるので、不要になったら認証後のプロシージャからコードは取り除いた方が安全でしょう。


以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。