Client-Initiated Backchannel Authentication (CIBA) 機能を使用するには、Enterprise プランまたは該当するアドオンが必要です。詳細は Auth0 Pricing を参照してください。
CIBA とメール通知を併用すると、ユーザーは、ブラウザーでリクエストを認証または承認するためにリダイレクトされるリンクが記載されたメールを受信します。
メール通知付きの CIBA を使用する場合、ユーザーはコンシューマーデバイスでログインしますが、認証の完了は、検証済みメールアドレス宛に送信されたリンクをクリックすることで行います。ユーザーが検証リンクをクリックするとブラウザーにリダイレクトされ、Auth0 が認証プロセスを追跡しユーザーの本人確認を行うために使用するセッションが作成されます。このセッションは、この例ではブラウザーである認証デバイスと、Smart TV などのコンシューマーデバイスとの間のギャップを埋めるために必要です。
次の図は、メール通知を用いた CIBA のエンドツーエンドフローを説明します。
次のセクションでは、メール通知を使用した CIBA におけるユーザー認証の仕組みをステップごとに詳しく説明します。
Auth0 を使用して CIBA メールリクエストを開始するには、次の条件を満たす必要があります。
ステップ 1: クライアント アプリケーションが CIBA リクエストを開始する
User Search API を使用して、CIBA リクエストを開始したい認可ユーザーを検索し、そのユーザー ID を取得します。
認可ユーザーのユーザー ID を取得したら、Authentication API または Auth0 の SDK を使用して、/bc-authorize エンドポイントに CIBA リクエストを送信します。
curl --location 'https://{yourDomain}.auth0.com/bc-authorize' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=<CLIENT_ID>' \
--data-urlencode 'client_secret=<CLIENT_SECRET>' \
--data-urlencode 'login_hint={ "format": "iss_sub", "iss": "https://{yourDomain}.auth0.com/", "sub": "<USER_ID>" }' \
--data-urlencode 'scope=<SCOPES>' \
--data-urlencode 'binding_message=<BINDING_MESSAGE>'
var response = await authenticationApiClient . ClientInitiatedBackchannelAuthorization (
new ClientInitiatedBackchannelAuthorizationRequest ()
{
ClientId = "<CLIENT_ID>" ,
Scope = "<SCOPES>" ,
ClientSecret = "<CLIENT_SECRET>" ,
BindingMessage = "<BINDING_MESSAGE>" ,
LoginHint = new LoginHint ()
{
Format = "iss_sub" ,
Issuer = "https://{yourDomain}.auth0.com/" ,
Subject = "<USER_ID>"
}
}
);
resp , err := authAPI . CIBA . Initiate ( context . Background (), ciba . Request {
ClientID : mgmtClientID ,
ClientSecret : mgmtClientSecret ,
Scope : "openid" ,
LoginHint : map [ string ] string {
"format" : "iss_sub" ,
"iss" : "https://{yourDomain}.auth0.com/" ,
"sub" : "<USER_ID>" ,
},
BindingMessage : "<BINDING_MESSAGE>" ,
})
// AuthClient インスタンスの作成
AuthAPI auth = AuthAPI . newBuilder (domain, clientId, clientSecret). build ();
// 認可を実行
Map < String , Object > loginHint = new HashMap <>();
loginHint . put ( "format" , "iss_sub" );
loginHint . put ( "iss" , "https://{yourDomain}.auth0.com/" );
loginHint . put ( "sub" , "<USER_ID>" );
Request < BackChannelAuthorizeResponse > request = auth . authorizeBackChannel ( "openid" , "<BINDING_MESSAGE>" , loginHint);
BackChannelAuthorizeResponse resp = request . execute (). getBody ();
パラメーター 説明 tenantテナント名。カスタムドメイン名の場合もあります。iss_sub フォーマットが使用されている場合、テナント名は iss クレーム内で渡されます。 client_idクライアントアプリケーションの識別子。 client_secretCIBA でユーザー認証を行うために使用されるクライアント認証方法。例として、クライアントシークレット、Private Key JWT、mTLS 認証などがあります。Private Key JWT または mTLS を使用している場合は、クライアントシークレットを含める必要はありません。 scopeopenid を必ず含める必要があります。 スコープには任意で offline_access を含めてリフレッシュトークンを要求できます。ただし、CIBA フローを用いたトランザクションの一度きりの認可では、リフレッシュトークンは不要であり、このコンテキストでは意味を持ちません。user_idlogin_hint 構造内で渡される、認可を行うユーザーのユーザー ID。iss_sub フォーマットが使用されている場合、ユーザー ID は sub クレーム内で渡されます。 ユーザー ID は外部プロバイダーによって異なるフォーマットになることがあります。requested_expiryCIBA セッションが有効となる最大期間(秒)。CIBA フローの requested expiry は 1 ~ 259200 秒(72 時間)の範囲で指定でき、デフォルトは 300 秒です。CIBA フローに対してカスタムの有効期限を設定するには、requested_expiry パラメーターを含めます。requested_expiry パラメーターは、CIBA が使用する通知チャネルを決定するのに役立ちます。requested_expiry を 300 以下(秒)に設定した場合、有効になっていれば CIBA はモバイルプッシュ通知チャネルを使用します。テナントに対して MFA を構成していない場合、CIBA リクエストは失敗します。requested_expiry を 301 ~ 259200 秒(72 時間)の範囲に設定した場合、有効になっていれば CIBA はメール通知チャネルを使用します。 binding_message認証デバイスと利用デバイス間で CIBA フローを関連付けるために使用される、人が読めるメッセージ。binding message は必須で、最大 64 文字まで指定できます。英数字と +-_.,:# の各文字のみを使用してください。
認可を行うユーザーごとにレート制限があり、そのユーザーには 1 分あたり 5 件を超えるリクエストは送信されません。
ステップ 2: Auth0 テナントが CIBA リクエストを受け付ける
Auth0 テナントが POST リクエストを正常に受信すると、そのリクエストを参照する auth-req-id を含むレスポンスが返されます。
{
"auth_req_id" : "eyJh..." ,
"expires_in" : 300 ,
"interval" : 5
}
auth_req_id の値は、CIBA フローの完了を確認するためポーリングを行う /token エンドポイントに渡されます。
ステップ 3: クライアントアプリケーションがレスポンスをポーリングする
Authentication API または SDK を使用して、grant_type に urn:openid:params:grant-type:ciba を指定し、/bc-authorize エンドポイントから受け取った auth_req_id を使用して /token エンドポイントを呼び出します:
curl --location 'https://{yourDomain}.auth0.com/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=<CLIEND_ID>' \
--data-urlencode 'client_secret=<CLIENT_SECRET>' \
--data-urlencode 'auth_req_id=<AUTH_REQ_ID>' \
--data-urlencode 'grant_type=urn:openid:params:grant-type:ciba'
var token = await authenticationApiClient . GetTokenAsync (
new ClientInitiatedBackchannelAuthorizationTokenRequest ()
{
AuthRequestId = response . AuthRequestId ,
ClientId = "<CLIENT_ID>" ,
ClientSecret = "<CLIENT_SECRET>"
}
);
token , err := authAPI . OAuth . LoginWithGrant ( context . Background (),
"urn:openid:params:grant-type:ciba" ,
url . Values {
"auth_req_id" : [] string { resp . AuthReqID },
"client_id" : [] string { clientID },
"client_secret" : [] string { clientSecret },
},
oauth . IDTokenValidationOptions {})
Request < BackChannelTokenResponse > tokenRequest = auth . getBackChannelLoginStatus (authReqId, "grant-type" );
BackChannelTokenResponse tokenResponse = tokenRequest . execute (). getBody ();
認可を行うユーザーがこのトランザクションを承認するまでの間は、次のようなレスポンスが返されます:
{
"error" : "authorization_pending" ,
"error_description" : "エンドユーザーの認可が保留中です"
}
ポーリング間隔はおおよそ 5 秒です。ポーリングを頻繁に行いすぎると、次のようなレスポンスが返されます。description の内容はバックオフ間隔に応じて変化します。
{
"error" : "slow_down" ,
"error_description" : "許可された頻度を超えてポーリングしています。10秒後に再試行してください。"
"interval" : 10
}
Error を解消するには、次のポーリング間隔(秒)になるまで待ってから /token エンドポイントをポーリングしてください。
ステップ 4: Auth0 がユーザーのメールアドレスにリンクを送信する
Auth0 認可サーバーは、認可対象ユーザーのユーザー ID を含む login_hint を使用して、認証デバイス上でユーザー認証を開始します。
Auth0 認可サーバーは、ユーザーの確認済みメールアドレスにメールを送信します。
メールには、ユーザーがクリックして認証を完了する必要がある検証リンクが含まれます。binding_message はリクエストコードとして表示されます。
リンクは /bc-verify エンドポイントへのリクエストを通じてユーザーのブラウザーにリダイレクトし、そこで consent クエリパラメーターが同意待ちの CIBA リクエストを参照します。
アクティブなセッションが見つからない場合、検証リンクによってユーザーに認証が求められます。ユーザーはリンクをクリックして認証処理を進めます。
認証するには、ユーザーは検証済みのメールアドレスとパスワードを入力します。ユーザーは、クライアントアプリケーションが CIBA リクエストを開始 した際に /bc-authorize エンドポイントへ送信した login_hint パラメーターで指定された資格情報を使用する必要があります。そうしない場合はエラーメッセージが表示され、ログアウトしてやり直す必要があります。
認証が完了すると、ブラウザーは Auth0 Consent API から取得した同意内容をユーザーに提示します。ここには binding_message、scope、audience が含まれます。スコープは RBAC ポリシーに従ってフィルタリングされます。詳細については、ロールベースのアクセス制御 を参照してください。
次のコードサンプルは、Auth0 Consent API からのレスポンス例です。
{
"id" : "cns_abc123" ,
"requested_details" : {
"audience" : "https://$tenant.auth0.com/userinfo" ,
"scope" : [ "openid" ],
"binding_message" : "21-49-38"
},
"created_at" : 1746693720
"expires_at" : 1746693750
}
この時点で、ユーザーは認証リクエストを承認するか拒否するかを選択できます。
ステップ 6: ブラウザーがユーザーの応答を Auth0 に送信する
ブラウザーはユーザーからの応答を Auth0 に送り返します。ユーザーが認証リクエストを承諾するか拒否するかに応じて、Auth0 は次の同意画面を表示します。これらの画面は、同意プロンプトを設定 してカスタマイズする必要があります。
ステップ 7: フロー完了後に Auth0 がユーザーの応答を受信する
クライアントアプリケーションは、/token エンドポイントからの応答を受信するとポーリングを終了します。CIBA フローでは常に、認可を行うユーザーからの承認または却下のいずれかの応答が必要であり、既存のグラントは参照されません。
ステップ 8: Auth0 がアクセストークンをクライアントアプリケーションに返す
ユーザーがメールのリクエストを拒否した場合、Auth0 は次のようなエラーレスポンスをクライアントアプリケーションに返します。
{
"error" : "access_denied" ,
"error_description" : "エンドユーザーが認可リクエストを拒否したか、リクエストの有効期限が切れています"
}
ユーザーがメールによるリクエストを承認すると、Auth0 はクライアントアプリケーションに次のようなアクセストークン を返します。
{
"access_token" : "eyJh..." ,
"id_token" : "eyJh..." ,
"expires_in" : 86400 ,
"scope" : "openid" ,
"token_type" : "Bearer"
}
refresh_token が含まれるのは、初回の /bc-authorize リクエストに offline_access スコープが含まれている場合のみです。