2023年6月6日火曜日

Azure ADのOIDC認証で取得したリフレッシュ・トークンを使ってアクセス・トークンを更新する

 KeycloakのOpen ID Connect認証で取得したリフレッシュ・トークンを使って、アクセス・トークンを更新する実装を見かけたので、Azure ADで同様の実装を試してみました。

以下から始まる一連の記事で行った実装への追加になります。

Microsoft OneDriveを操作するAPEXアプリの作成(1) - Azure ADへのアプリ登録

リフレッシュ・トークンは、Azure ADを使ったOpen ID Connect認証の応答であるJSONデータに含まれています。Oracle APEXの認証スキームの認証後のプロシージャに、リフレッシュ・トークンの取得と保存を行うコードを記述します。

取得したリフレッシュ・トークンを保存するために、アプリケーション・アイテムとしてG_REFRESH_TOKENを作成します。

共有コンポーネントアプリケーション・アイテムを開きます。


作成をクリックし、アプリケーション・アイテムG_REFRESH_TOKENを作成します。有効範囲アプリケーションセキュリティセッション・ステート保護はデフォルトの制限付き - ブラウザから設定不可のまま変更しません。トークンにエスケープされるような特殊文字は含まれないと考えているので、特殊文字をエスケープオンにしています。リフレッシュ・トークンを画面に表示することはないため、オフにしても問題ないでしょう。

アプリケーション・アイテムの作成をクリックします。


アプリケーション・アイテムが作成されます。


Azure ADを使っている認証スキームを開き、ソースPL/SQLコードに以下を記述します。Azure ADの応答からrefresh_tokenを取り出し、アプリケーション・アイテムG_REFRESH_TOKENに保存しています。


ソースに記述したプロシージャpost_authを、ログイン・プロセス認証後のプロシージャ名に設定します。

変更の適用をクリックして、保存します。


ワークスペース・ユーティリティWeb資格証明を開きます。

すでにOpen ID Connectによる認証に使用しているWeb資格証明が登録済みです。これは認証タイプOAuth2クライアント資格証明フローです。

同じクライアントIDクライアント・シークレットを使った基本認証Web資格証明を作成します。リフレッシュ・トークンを使ったアクセス・トークンの取得に、このWeb資格証明を使います。


Azure ADの画面より、登録済みのアプリケーションのアプリケーション(クライアントID)を確認し、コピーします。


クライアントの資格情報を開き、クライアント・シークレットを取得します。作成直後を除きコピーできないことから、再作成が必要な場合もあります。

この値もコピーしておきます。


リフレッシュ・トークンを発行するには、APIのアクセス許可(いわゆるスコープ - scope)にoffline_accessが含まれている必要があります。


クライアント・シークレットを再作成した場合は、認証タイプOAuth2クライアント資格証明フローWeb資格証明クライアント・シークレットまたはパスワードを更新します。


認証タイプ基本認証としたWeb資格証明を作成します。

名前はMS Azure Cred Basic静的IDMS_AZURE_AD_BASICとしています。認証タイプ基本認証を選択し、クライアントIDまたはユーザー名クライアント・シークレットまたはパスワードは、OAuth2クライアント資格証明フローと同じ情報を設定します。


アクセス・トークンのリフレッシュを行うための準備は以上になります。

実際にアクセス・トークンをリフレッシュする実装を行います。

ホーム・ページにリフレッシュを行うボタンRefresh Tokenを作成します。


ページ・デザイナホーム・ページを開き、ボタンを作成します。識別ボタン名REFRESH_TOKENラベルRefresh Token動作アクションはデフォルトのページの送信を選択します。


プロセス・ビューを開き、ボタンREFRESH_TOKENをクリックしたときに実行するプロセスを作成します。

識別名前Refresh Tokenタイプとしてコードを実行を選択します。ソースPL/SQLコードとして以下を記述します。


サーバー側の条件ボタン押下時REFRESH_TOKENを指定します。


以上で、アクセス・トークンを更新するボタンができました。

動作を確認してみます。

アプリケーションを実行し、Azure ADを使ってサインインをします。サインインに成功すると、ホーム・ページが開きます。


以下のMS Graph APIを呼び出し、ドライブの一覧を表示します。

https://graph.microsoft.com/v1.0/me/drives


認証スキームで使用しているWeb資格証明タイプOAuth2クライアント資格証明フロー)を開きます。ストアド・トークンアクセス・トークン(セッション)、つまりアクセス・トークンが保存されていることを確認します。

トークンのクリアをクリックします。


ページがWeb資格証明の一覧に戻るので、再度、対象のWeb資格証明を開きます。

アクセス・トークン(セッション)0になっています。


ボタンSubmitをクリックすると無効なURLというエラーが発生します。アクセス・トークンが無効(正確にいうと無くなっている)になっているので、ボタンRefresh Tokenをクリックし、アクセス・トークンを再取得します。


Web資格証明のページを再ロードすると、アクセス・トークン(セッション)1になっており、新たにアクセス・トークンが保存されていることが確認できます。


再度MS Graph APIを呼び出すと、今度はAPIが正常に応答し、アクセス・トークンが有効であることが確認できます。

APEXアプリケーションの最大セッションの長さ(秒)はデフォルトで通常3600秒なので、このままの設定であればリフレッシュ・トークンを使ってアクセス・トークンを更新する意味はそれほどない(アクセス・トークンの有効期間も3600秒であるため)かもしれません。

APEXアプリケーションの最大セッション長は、アプリケーション定義セキュリティセッション管理最大セッションの長さ(秒)を変更することで、長くすることができます。


以上になります。

以前に公開しているアプリケーションのエクストポートに、今回の実装を追加しました。
https://github.com/ujnak/apexapps/blob/master/exports/onedrive-operation.zip

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