特定のトランザクションを認証するためにSCAステップアップ認証および動的リンキング を適用することで、ハイリーレギュレーテッドアイデンティティは、コンテキストに基づいた強力な顧客認証(SCA)を使用したトランザクション認可を可能にします。1回の操作のトランザクション詳細を明示的に認可するために、第二認証要素でユーザーにチャレンジします。これは、金融グレードのセキュリティを必要とする以下のユースケースで役立ちます。
銀行間振込、操作履歴へのアクセス、アクセス認証情報の変更の承認など、自身のサービスで実行する機密性の高い操作のセキュリティ保護。
電子決済の承認や、アカウント検証への1回限りのアクセス許可など、サードパーティーサービスから要求される機密性の高い操作のセキュリティ保護。
この記事では、銀行間振込を承認するエンドツーエンドの流れを通して説明します。同じトランザクション認可フローが、他のユースケースにも適用できます。
トランザクション認可はAPIごとに構成しなければなりません。有効化したトランザクション認可は、そのAPIのスコープとauthorization_details.typesに適用されます。
詳細なトランザクション認可データやその他の機密性が高い、または規制されているデータはauthorization_details外に渡さないください。
構成したいAPIまたはリソースサーバーについては、「リッチ認可要求(RAR)を構成する 」の手順に従ってください。
transactional-authorization-with-mfaをconsent_policyに設定します。
使用するauthorization_details.typesを登録します。
以下の図は、コンテキストに基づいたSCAを使用したトランザクション認可のエンドツーエンドのフローを示しています。以下の4つの主要な段階があります。
ユーザーをトランザクションの詳細と共にAuth0に安全にリダイレクトします。この段階では、フロントチャネル(例:ブラウザー)に機密情報を公開することは避けます。
ユーザーの認証の後に、動的ポリシーを適用します。Actions を使用して、トランザクションの詳細、および外部APIなどのソースから取得したその他の情報に基づいて、次の段階を動的に決定できます。詳細については、「動的ポリシーの適用 」をお読みください。
第二認証要素でユーザーにチャレンジし、ユーザーが明示的に承認できるようにトランザクションの詳細を表示します。この段階は、Actionsを使用して適用する認証要素によって異なります。
アクセストークンを取得し、機密性の高い操作を進めます。APIは、アクセストークンに関連する承認済みのトランザクション詳細を検証します。
以下のセクションでは、各段階について詳細に説明します。
トランザクション詳細を伝えてAuth0にリダイレクト
Auth0での認証後、ユーザーは最初にWebアプリケーションにアクセスします。このユースケースの例に従うと、その後ユーザーは、連絡先の1つへの送金を要求します。
金融グレードのセキュリティ標準を満たすために、ハイリーレギュレーテッドアイデンティティは、トランザクション詳細をブラウザーから隠すために、プッシュ認可要求(PAR)を使用します。ブラウザーを通して/authorizeエンドポイントにクエリパラメーターを送信する代わりに、PARは、POST要求を使用して、バックエンドからパラメーターを特別な/parエンドポイントに直接送信します。セットアップの方法については、「プッシュ認可要求(PAR)を構成する 」をご覧ください。
PAR要求本文で、トランザクションの詳細は、authorization_details JSONオブジェクトの一部として送信されます。
"authorization_details": [
{
"type": "money_transfer",
"instructedAmount": {
"amount": 150,
"currency": "USD"
},
"sourceAccount": "xxxxxxxxxxx1234",
"destinationAccount": "xxxxxxxxxxx9876",
"beneficiary": "Hanna Herwitz",
"subject": "A Lannister Always Pays His Debts"
}
]
トランザクションに基づいてどの認証要素を使用するかを決定するために、Actionsを使用してauthorization_detailsを確認します。authorization_detailsおよびRARとの使用方法の詳細については、「Rich Authorization Requestsを使用した認可コードフロー 」をお読みください。
FAPI 1高度なセキュリティのコンプライアンス要件を満たしたい場合は、/parまたは/tokenエンドポイントに対してバックエンドを認証するために、公開鍵の暗号方式も使用する必要があります。これは、クライアントシークレットを送信するよりも、安全です。Auth0は、以下の公開鍵の暗号認証方法を提供しています。
PAR要求に対する成功の応答を受け取った後、ユーザーをAuth0テナントの/authorizeエンドポイントにリダイレクトします。PAR応答で受け取ったrequest_uriパラメーターとclient_idを専用クエリパラメーターとして追加します。こうして、機密情報をブラウザーから効果的に隠すことができます。
SSO を使用せずにユーザーがログインして、ブラウザーがAuth0テナントの/authorizeエンドポイントをヒットした場合、Auth0はユーザーの認証を試みます。この銀行間振込の承認の例では、Auth0は、Webアプリケーションにアクセスするために、すでにユーザーを認証しています。しかし、電子決済などのために、サードパーティがユーザーをリダイレクトした場合、Auth0は、ユーザーにログイン画面を表示します。認証フローの詳細については、認証 ドキュメントをご覧ください。
Auth0がユーザーの認証に成功したら、Auth0は、ログイン後のActions をトリガーし、ユーザー、アプリ、使用された認証要素に関するトランザクション詳細、さらにログイン後のイベントオブジェクト の詳細を公開します。ログイン後のイベントオブジェクト内のevent.transaction.requested_authorization_detailsプロパティには、前段階で受け取った認証要求に関する詳細が含まれています。
ログイン後のイベントオブジェクト を使用して、このトランザクションの処理方法について決定します。たとえば以下のコード例で示すように、外部のリスクエンジンにトランザクション詳細を送信して、リスクレベルを評価した後に、SMSを使用したステップアップ認証を要求するかどうかを決定できます。
exports . onExecutePostLogin = async ( event , api ) => {
if ( event . transaction ?. requested_authorization_details . some ( e => e . type === 'money_transfer' )) {
const axios = require ( 'axios' );
//details to contact risk evaluation engine
const risk_url = 'https://risk.example.org/score' ;
const risk_options = {
headers: {
'Content-Type' : 'application/json'
}
};
const tx_data = {
email: event . user . email ,
authorization_details: event . transaction ?. requested_authorization_details
};
//send operation details to risk evaluation engine
var risk = await axios . post ( risk_url , tx_data , risk_options );
//if it is a risky operation use push to authorize
if ( risk . data . score >= 2 ) {
api . authentication . challengeWith ({ type: 'push-notification' , options: { otpFallback: false }});
}
}
};
またログイン後のActionは、トランザクションの汎用一意識別子(UUID)を保有するevent.transaction.linking_idを公開します。後で、Auth0がトランザクションの承認をユーザーに促すとき、linking_idは、Dynamic Linking の参照を提供します。また、特定のトランザクションの認可の詳細と、あなた側のAPI呼び出しを関連づけるために、カスタムクレーム としてアクセストークンにlinking_idを追加できます。これは、 Auth0がテナントログにlinking_idを含めるため、トレーサビリティに役立ちます。
トランザクションの詳細の承認を得るためにユーザーにチャレンジする
ユーザーが登録した要素、セッションにより満たされた要素、および/またはご自身の好みに応じて、使用する認証要素をカスタマイズできます。また、ユーザーが選択できる代替手段も提供できます。詳細については、「新しいユニバーサルログインでのMFA選択をカスタマイズする 」をご覧ください。
さらにSMS、メール、WebAuthnについては、authorization_detailsおよびその他のトランザクションの詳細からの表示したい情報を使用して、Auth0がユーザーに表示する同意画面をカスタマイズできます。詳細については、「Rich Authorization Requests(RAR)を構成する 」をお読みください。プッシュ通知については、モバイルアプリケーションがエンドユーザーにトランザクション詳細を表示するため、これが適用されません。
以下のセクションでは、トランザクション認可のために構成できる様々な認証要素について説明します。
Auth0が消費デバイス(例、トランザクションを開始したラップトップ)に多要素認証(MFA )の待ち画面をユーザーに提示している間、ユーザーの登録済みのデバイスにプッシュ通知を送信します。
プッシュ通知については、モバイルアプリケーションが、明示的な承認のためにユーザーにトランザクション詳細を表示する責任を負います。これを行うには、Actionsを使用して、ユーザーに表示したいトランザクション詳細と一緒にlinking_idを外部サーバーまたはエンドポイントに保管して、たったの数分で利用できるようにします。その後、以下のコード例で示すように、プッシュ通知でユーザーにチャレンジします。otpFallback: falseのオプションを追加して、OTPを手動で入力するフォールバックのオプションを禁止することを忘れないでください。
exports.onExecutePostLogin = async (event, api) => {
if (event.transaction?.requested_authorization_details.some(e => e.type === 'money_transfer')) {
const axios = require('axios');
//details to store tx_details in external server
const tx_server_url = 'https://consent.example.org/transactions';
const tx_server_options = {
headers: {
'Content-Type': 'application/json'
}
};
const tx_data = {
email: event.user.email,
authorization_details: event.transaction?.requested_authorization_details,
linking_id: event.transaction.linking_id
};
//store the transaction details in an external endpoint
var response = await axios.post(tx_server_url, tx_data, tx_server_options);
//event.transaction.linking_id is automatically added to the push challenge
api.authentication.challengeWith({ type: 'push-notification', options: {otpFallback: false}});
//add unique transaction_id to access token for traceablity
api.accessToken.setCustomClaim('transaction_id', event.transaction.linking_id);
}
};
Actionsからapi.authentication.challengeWithの前にapi.multifactor.enable('any', { allowRememberBrowser: false })を呼び出すと、このデバイスを記憶するオプションが削除され、ユーザーに対し、全トランザクションでプッシュチャレンジの検証を強制することができます。
プッシュ通知は、Auth0 Guardian SDK がモバイルアプリケーションに渡す、event.transaction.linking_idを含みます。通信時、プロパティ名は、txlnkidに短縮されます。linking_idを使用して、モバイルアプリケーションは、トランザクション詳細を取得し、ユーザーに表示できます。ユーザーがこの操作を承認または拒否すると、モバイルアプリケーションは、MFAチャレンジをそれぞれ許可または拒否します。トランザクションは、操作の完了 の段階へと進みます。
注意: プッシュ通知を開くユーザーのIDを検証するには、モバイルアプリケーションに生体認証を追加できます。詳細については、「MFAのためにデバイス生体認証を使ってWebAuthnを構成する 」をご覧ください。
ユーザーにチャレンジする認証要素として、携帯電話、メール、Webauthnをセットアップすることもできます。これらの認証要素については、Auth0は、対応するMFA待ち画面をユーザーに提示します。ユーザーがMFA待ち画面のチャレンジを検証した後、Auth0は、明示的な承認のために、ユーザーにトランザクション詳細を表示します。承認ステップが正しく機能するように、Rich Authorization Requestsを構成する 必要があることを覚えておいてください。
携帯電話の認証要素については、Auth0は、SMSまたは音声を通して、ユーザーに検証コードを送信します。以下のスクリーンショットは、Auth0がSMSを通してコードを送信した後のMFA待ち画面を示しています。
Actionsからapi.authentication.challengeWithの前にapi.multifactor.enable('any', { allowRememberBrowser: false })を呼び出すと、このデバイスを記憶するオプションが削除され、ユーザーに対し、全トランザクションでプッシュチャレンジの検証を強制することができます。
ユーザーは、検証コードが記載されたSMSを受け取ります。
ユーザーがMFA待ち画面に検証コードを入力したら、Auth0は、同意画面でトランザクション詳細をユーザーに提示します。ユーザーがトランザクション詳細を承認または拒否したら、トランザクションは、操作の完了 の段階へと進みます。
メールおよびWebAuthnは、同じトランザクション承認フロー、および類似のMFA待ち画面と明示的な承認画面を使用します。
第二認証要素でユーザーにチャレンジしない場合、Auth0は、同意画面で、トランザクション詳細の明示的な承認をユーザーに求めます。
操作を完了するために、Auth0は、標準の認可コードフローに従います。トランザクションが承認された場合、ユーザーブラウザは、認証コードと共にアプリケーションにリダイレクトされ、その後認証コードは、JSON Web Encryption を使用して暗号化されたアクセストークンに交換されます。アクセストークンは、最初に渡したauthorization_detailsを含んでいます。以下のコード例は、暗号化されたアクセストークンの内容を示しています。
{
"iss" : "https://my_tenant.auth0.com/" ,
"sub" : "auth0|me" ,
"aud" : "https://myapi.zewobnak.com" ,
"iat" : 1683661385 ,
"exp" : 1683747785 ,
"azp" : "my_client" ,
"transaction_linking_id" : "ce4842e8-2894-418a-b1f9-39a330cd4911" ,
"authorization_details" : [
{
"type" : "money_transfer" ,
"instructedAmount" : {
"amount" : 150 ,
"currency" : "USD"
},
"sourceAccount" : "xxxxxxxxxxx1234" ,
"destinationAccount" : "xxxxxxxxxxx9876" ,
"beneficiary" : "Hanna Herwitz" ,
"subject" : "A Lannister Always Pays His Debts" ,
}
]
}
送金を促すAPIにアクセストークンを渡します。その後APIは、金額、送信元、送信先などのトランザクション詳細を検証するために、アクセストークンのauthorization_detailsを確認します。検証後、送金が正常に実行され、承認画面が表示されます。
いずれかの段階でトランザクションが拒否された場合、ユーザーブラウザは、access_deniedエラーコードを表示します。