メインコンテンツへスキップ
Auth0 Actions を使用すると、カスタムコードで認証をカスタマイズできます。複数のカスタムドメイン を使用している場合は、Actions からカスタムドメイン情報にアクセスして、ドメイン固有のロジックを実装したり、ユーザーを組織に振り分けたり、アクセス ポリシーを適用したり、通知をカスタマイズしたりできます。

カスタムドメイン情報へのアクセス

Actions では、event.custom_domain オブジェクトを通じてカスタムドメインの情報にアクセスできます。このオブジェクトには、ドメイン名と、そのドメインに設定されたすべてのメタデータが含まれます。

利用可能なトリガー

event.custom_domain オブジェクトは、以下の Action トリガーで使用できます。
TriggerEvent object reference
Credentials Exchangeイベントオブジェクト
Custom Email Providerイベントオブジェクト
Custom Phone Providerイベントオブジェクト
Post Loginイベントオブジェクト
Post User Registrationイベントオブジェクト
Post Password Changeイベントオブジェクト
Pre User Registrationイベントオブジェクト
Reset Password Post Challengeイベントオブジェクト
event.custom_domain オブジェクトは、リクエストがカスタムドメイン経由で発生したトリガーでのみ使用できます。カスタムドメインが使用されていない場合、このプロパティは undefined になります。

イベントオブジェクトの構造

ドメインメタデータで設定された login.example.com ドメインを使用する場合:
キー
allow_listexample1.com,example2.com
exports.onExecutePostLogin = async (event, api) => {
  console.log(event.custom_domain);
};
コンソールには次のように出力されます:
{
  "domain": "login.example.com",
  "domain_metadata": {
    "allow_list": "example1.com,example2.com"
  }
}

一般的な使用例

ドメインに基づく条件分岐

カスタムドメインと正規ドメインのどちらを使用しているかに応じて、異なるルールを適用します。
exports.onExecutePostLogin = async (event, api) => {
  const domain = event.custom_domain?.domain;

  if (
    domain === undefined ||
    domain.includes('.auth0.com') || // パブリッククラウド
    domain.includes('.auth0app.com') // プライベートクラウド
  ) {
    return api.access.deny('Please use the custom domain to log in.');
  }
};

メールアドレスのドメインに基づくアクセス制御

カスタムドメインメタデータを使用して、メールアドレスのドメインごとのアクセスポリシーを適用します。
const getEmailDomain = (email) => {
  if (!email || typeof email !== 'string') {
    return null;
  }

  const parts = email.split('@');
  
  // '@' がちょうど1つ存在すること(または少なくともドメイン部分が存在すること)を確認する
  // "invalid-email" や "user@" のようなケースに対応する
  if (parts.length < 2 || !parts[1]) {
    return null;
  }

  return parts[1].toLowerCase().trim();
}

exports.onExecutePreUserRegistration = async (event, api) => {
  const domain = event.custom_domain?.domain;

  if (domain === undefined) {
    return api.access.deny(
      'access_denied',
      `Access denied - Users cannot access without custom domain.`
    );
  }

  const email = event.user.email;
  
  if (email === undefined) {
    return api.access.deny(
      'access_denied',
      `Access denied - Users cannot access without email.`
    );
  }

  const domainAllowList = event.custom_domain?.domain_metadata?.allow_list?.split(',') || [];
  const emailDomain = getEmailDomain(email);

  if (domainAllowList.includes(emailDomain) === false) {
    return api.access.deny(
      'access_denied',
      `Access denied - Users from ${emailDomain} cannot access ${domain}.`
    );
  }
};

アプリケーションメタデータに基づくアクセス制御

アプリケーションメタデータとドメインメタデータを使用して、アプリケーション グループとドメイン グループのアクセス ポリシーを適用します。
exports.onExecuteCredentialsExchange = async (event, api) => {
  const domain = event.custom_domain?.domain;
  
  if (
    domain === undefined ||
    domain.includes(event.tenant.id)
  ) {
    return; // 正規ドメインの場合はスキップ
  }

  const applicationGroup = new Set(event.client.metadata?.domain_group?.split(',') || []);
  const domainGroup = event.custom_domain?.domain_metadata?.domain_group?.split(',') || [];
  const intersection = domainGroup.filter(x => applicationGroup.has(x));

  if (intersection.length === 0) {
    return api.access.deny(
      'invalid_request',
      `Access denied - Cannot get access from application ${event.client.name} and ${domain}.`
    );
  }
};

接続メタデータに基づくアクセス制御

接続メタデータとドメインメタデータを使用して、接続グループおよびドメイングループに対するアクセス ポリシーを適用します:
exports.onExecutePostLogin = async (event, api) => {
  const domain = event.custom_domain?.domain;

  if (domain === undefined) {
    return api.access.deny(
      `Access denied - Users cannot access without custom domain.`
    );
  }

  const connectionGroup = new Set(event.connection.metadata?.domain_group?.split(',') || []);
  const domainGroup = event.custom_domain?.domain_metadata?.domain_group?.split(',') || [];
  const intersection = domainGroup.filter(x => connectionGroup.has(x));

  if (intersection.length === 0) {
    return api.access.deny(
      `Access denied - Users cannot access connection ${event.connection.name} from ${domain}.`
    );
  }
};

組織メタデータに基づくアクセス制御

組織とドメインのメタデータを使用して、組織グループおよびドメイングループのアクセスポリシーを適用します。
exports.onExecutePostLogin = async (event, api) => {
  const organization = event.organization;

  if (organization === undefined) {
    return; // 組織認証以外はスキップ
  }

  const domain = event.custom_domain?.domain;

  if (domain === undefined) {
    return api.access.deny(
      `Access denied - Users cannot access without custom domain.`
    );
  }

  const organizationGroup = new Set(organization.metadata?.domain_group?.split(',') || []);
  const domainGroup = event.custom_domain?.domain_metadata?.domain_group?.split(',') || [];  
  const intersection = domainGroup.filter(x => organizationGroup.has(x));

  if (intersection.length === 0) {
    return api.access.deny(
      `Access denied - Users cannot access organization ${organization.name} from ${domain}.`
    );
  }
};

リージョン別のリクエスト

カスタムドメインメタデータに基づいて、リージョン固有の外部サービスにリクエストを送信します。
exports.onExecuteCustomEmailProvider = async (event, api) => {
  const regionServiceEndpoint = event.custom_domain?.domain_metadata?.region_service_endpoint;

  if (regionServiceEndpoint === undefined) {
    return api.notification.drop(`Missing regional service endpoint configuration at custom domain.`);
  }

  const notification = event.notification;
  const messageBody = {
    body: notification.html
  };

  try {
    await fetch(regionServiceEndpoint, {
      method: 'POST',
      headers: {
        'X-API-Key': event.secrets.API_KEY,
      },
      body: JSON.stringify(messageBody),
    });
  } catch (err) {
    api.notification.drop('External service failure');
  }
};

詳細はこちら

Actions のドキュメント

イベントオブジェクトのリファレンス