Highly Regulated Identity では、Authorization Code Flow にステップアップ (MFA) を適用することで、トランザクション認可を実現できます。ステップアップ MFA では、1 回限りの操作に関するトランザクションの詳細を明示的に認可するために、ユーザーに第 2 の認証要素を求めます。これは、金融グレードのセキュリティが求められるユースケースで特に有効です。
- 銀行振込の承認、操作履歴へのアクセス、アクセス資格情報の変更など、自社サービスで実行される機密性の高い操作を保護する。
- デジタル決済の承認や、アカウント確認のための 1 回限りのアクセス許可など、サードパーティサービスから要求される機密性の高い操作を保護する。
この記事では、銀行振込を承認するエンドツーエンドの流れを説明します。同じトランザクション は、他のユースケースにも適用できます。
トランザクション認可は、API ごとに設定する必要があります。有効にすると、その API のスコープと authorization_details.types に適用されます。
authorization_details の外に、きめ細かなトランザクション認可データや、その他の機密データまたは規制対象データを渡さないでください。
始める前に、リッチ認可リクエストを設定する の手順に従って、API または の authorization_details.types を登録してください。
次の図は、Contextual SCA を使用した トランザクション認可 のエンドツーエンドフローを示しています。主なフェーズは 4 つあります。
- トランザクションの詳細とともに、ユーザーを安全に Auth0 にリダイレクトします。このステップでは、フロントチャネル (例: ブラウザー) で機密情報が漏れないようにしてください。
- ユーザーの認証後に動的なポリシーを適用します。Actions を使用すると、トランザクションの詳細や、外部 API などのソースから取得したその他の情報に基づいて、次のステップを動的に決定できます。詳しくは、動的なポリシーを適用する を参照してください。
- 第 2 の認証要素でユーザーに追加認証を求め、ユーザーが明示的に承認できるようにトランザクションの詳細を表示します。このステップは、Actions を使用して適用する認証要素として何を選択したかによって異なります。
- アクセストークンを取得し、機密性の高い操作を続行します。API は、アクセストークンに関連付けられた、承認済みのトランザクション詳細を検証します。
以降のセクションでは、各フェーズを詳しく説明します。
トランザクションの詳細を伝達し、Auth0 にリダイレクトする
ユーザーはまず、Auth0 で認証した後、お客様の Web アプリケーションにアクセスします。今回のユースケース例では、その後、ユーザーは連絡先の 1 人への送金をリクエストします。
金融グレードのセキュリティ標準を満たすため、Highly Regulated Identity では、トランザクションの詳細をブラウザーから隠す目的で Pushed Authorization Requests (PAR) を使用します。ブラウザー経由で /authorize エンドポイントにクエリーパラメーターを送信する代わりに、PAR では POST リクエストを使用して、バックエンドから専用の /par エンドポイントへパラメーターを直接送信します。設定方法については、Configure Pushed Authorization Requests を参照してください。
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 の詳細と、PAR と併用する方法については、リッチ認可リクエストを使用した Authorization Code Flowを参照してください。
FAPI 1 Advanced Security の準拠要件を満たすには、公開鍵暗号方式も使用して、バックエンドを /par または /token エンドポイントに対して認証する必要があります。これは、 を送信するよりも安全です。Auth0 では、次の公開鍵暗号方式による認証方法を提供しています。
PAR リクエストに対する成功レスポンスを受信したら、ユーザーを Auth0 テナントの /authorize エンドポイントにリダイレクトします。PAR レスポンスで受け取った request_uri パラメーターと client_id のみをクエリパラメーターとして追加することで、機密情報を実質的にブラウザーから隠すことができます。
ユーザーがを使用せずにログインし、ブラウザーがAuth0テナントの/authorizeエンドポイントにアクセスすると、Auth0はそのユーザーの認証を試みます。銀行振込の承認という本ガイドの例では、ユーザーがWebアプリケーションにアクセスするための認証は、すでにAuth0によって完了しています。しかし、デジタル決済のようにサードパーティによってユーザーがリダイレクトされた場合は、Auth0がユーザーにログイン画面を表示します。認証フローの詳細については、Authenticateのドキュメントを参照してください。
Auth0がユーザーの認証に成功すると、Auth0はログイン後のActionsをトリガーします。これにより、ユーザー、アプリ、使用された認証要素などに関するトランザクションの詳細が、post-login event objectで参照できるようになります。この post-login event object では、event.transaction.requested_authorization_detailsプロパティに、前のステップで受け取った認可リクエストの詳細が含まれます。
post-login event objectを使用して、トランザクションをどのように進めるかを判断します。たとえば、トランザクションの詳細を外部のリスクエンジンに送信し、リスクレベルを評価したうえで、次のコードサンプルに示すように、smsを使用したステップアップ認証を要求するかどうかを決定できます。
exports.onExecutePostLogin = async (event, api) => {
if (event.transaction?.requested_authorization_details.some(e => e.type === 'money_transfer')) {
const axios = require('axios');
//リスク評価エンジンへの接続情報
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
};
//操作の詳細をリスク評価エンジンに送信する
var risk = await axios.post(risk_url, tx_data, risk_options);
//リスクの高い操作の場合はプッシュ通知で認可する
if (risk.data.score >= 2) {
api.authentication.challengeWith({ type: 'push-notification', options: {otpFallback: false}});
}
}
};
ユーザーが登録済みの認証要素、現在のセッションですでに満たしている要素、または独自の条件に応じて、使用する認証要素をカスタマイズできます。また、ユーザーが選択できる代替手段を提示することもできます。詳しくは、New Universal Login で MFA 選択をカスタマイズするを参照してください。
さらに、SMS、メールアドレス、WebAuthn では、authorization_details やその他のトランザクション詳細のうち表示したい情報を使って、Auth0 がユーザーに表示する同意画面をカスタマイズできます。詳しくは、リッチ認可リクエストを設定するを参照してください。プッシュ通知には適用されません。トランザクション詳細をエンドユーザーに表示するのはモバイルアプリケーションであるためです。
以下のセクションでは、トランザクション認可用に設定できるさまざまな認証要素について説明します。
Auth0 が利用側のデバイス (例: トランザクションの開始元であるノート PC) に Multi-Factor Authentication (MFA) の待機画面を表示している間に、ユーザーが登録済みのモバイルデバイスへプッシュ通知を送信します。
プッシュ通知では、モバイルアプリケーションがトランザクションの詳細をユーザーに表示し、ユーザーによる明示的な承認を求める役割を担います。プッシュ通知をトリガーする際に、オプション otpFallback: false を追加すると、OTP を手動で入力するフォールバックオプションを無効にできます。
authorization_details をユーザーに表示するには、モバイルアプリケーションが txlnkid パラメーターからそれらを取得する必要があります。Auth0 Guardian SDK は、プッシュ通知を介して txlnkid パラメーターをテナントからモバイルアプリケーションに渡します。
モバイルアプリケーションが Guardian SDK 経由でプッシュ通知を受信すると、Auth0 Consent API から authorization_details を含む同意の詳細を取得できます。
let device: AuthenticationDevice = // 登録時に取得したオブジェクト
if let consentId = notification.transactionLinkingId {
Guardian
.consent(forDomain: {yourTenantDomain}, device: device)
.fetch(consentId: consentId, notificationToken: notification.transactionToken)
.start{result in
switch result {
case .success(let payload):
let authorizationDetails = payload.requestedDetails.authorizationDetails
case .failure(let cause):
// 問題が発生しました
}
}
}
if (notification.getTransctionLinkingId() != null) {
guardian
.fetchConsent(notification, enrollment)
.start(new Callback<Enrollment> {
@Override
void onSuccess(RichConsent consentDetails) {
List<Map<String, Object>> authorizationDetails = consentDetails
.getRequestedDetails()
.getAuthorizationDetails();
}
@Override
void onFailure(Throwable exception) {
if (exception instanceof GuardianException) {
GuardianException guardianException = (GuardianException) exception;
if (guardianException.isResourceNotFound()) {
// トランザクションに関連付けられた同意はありません
}
}
// 問題が発生しました
}
});
}
post-login Action から api.authentication.challengeWith() の前に api.multifactor.enable() を呼び出すと、このデバイスを記憶するオプションを削除し、すべてのトランザクションでユーザーにプッシュチャレンジの検証を必須にできます。詳しくは、Action Triggers: post-login - API object を参照してください。
ユーザーが操作を承認または拒否すると、モバイルアプリケーションは MFA チャレンジを許可または拒否できます。トランザクションは 操作を完了する フェーズに進みます。
電話番号、メールアドレス、または WebAuthn を認証要素として設定し、ユーザーにチャレンジを求めることもできます。これらの認証要素では、Auth0 は対応する MFA 待機画面をユーザーに表示します。ユーザーが MFA 待機画面でチャレンジを完了すると、Auth0 は明示的な承認を得るためにトランザクションの詳細をユーザーに表示します。承認ステップを正しく機能させるには、Configure リッチ認可リクエスト を設定しておく必要があることに注意してください。
電話番号の認証要素では、Auth0 は SMS または音声通話でユーザーに確認 code を送信します。次のスクリーンショットは、Auth0 が SMS で code を送信した後の MFA 待機画面を示しています。
Actions から、api.authentication.challengeWith の前に api.multifactor.enable('any', { allowRememberBrowser: false }) を呼び出すと、このデバイスを記憶するオプションを無効にし、すべてのトランザクションでユーザーに push チャレンジの検証を必須にできます。
その後、ユーザーは確認 code を含む SMS を受信します。
ユーザーが MFA 待機画面で確認 code を入力すると、Auth0 は同意画面でトランザクションの詳細をユーザーに表示します。ユーザーがトランザクションの詳細を承認または拒否すると、トランザクションは Complete the operation フェーズに進みます。
メールアドレスと WebAuthn でも、同じトランザクション承認フローと、同様の MFA 待機画面および明示的な承認画面が使用されます。
第2の認証要素によるチャレンジをユーザーに求めない場合、Auth0 は同意画面を表示して、トランザクションの詳細に対する明示的な承認を求めます。
操作を完了するために、Auth0 は標準の Authorization Code Flow に従います。トランザクションが承認されると、ユーザーのブラウザーは認可コードとともにアプリケーションにリダイレクトされ、その認可コードは続いて 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 エラーコードが表示されます。