PAM ロールのアクティブ化中または SSPR で API を介してカスタム多要素認証プロバイダーを使用する

MIM のお客様には、SSPR と PAM のシナリオで多要素認証を行う 2 つのオプションがあります。

  • カスタムの 1 回限りのパスワード デリバリー プロバイダーを使用します。これは、MIM SSPR シナリオのみで使用でき、「Configure Self-Service Password Reset with OTP SMS Gate」 (OTP SMS ゲートでセルフサービス パスワード リセットを構成する) のガイドに記載されています。
  • カスタムの多要素認証のテレフォニー プロバイダーを使用します。 これは、この記事で説明している MIM SSPR と PAM のシナリオ両方で使用できます。

この記事では、API とお客様が開発した統合 SDK を使用して、カスタムの多要素認証プロバイダーを使用して MIM を使用する方法の概要を説明します。

前提条件

MIM でカスタム多要素認証プロバイダー API を使用するには、次のものが必要です。

  • 全候補ユーザーの電話番号
  • MIM の修正プログラム 4.5.202.0 以降 (アナウンスについてはバージョン履歴に関する記事を参照)
  • SSPR または PAM に対する MIM サービスの構成

カスタムの多要素認証コードを使用したアプローチ

手順 1: MIM サービスがバージョン 4.5.202.0 以降であることを確認する

MIM の修正プログラムのバージョン 4.5.202.0 以降をダウンロードおよびインストールします。

手順 2: IPhoneServiceProvider インターフェイスを実装する DLL を作成する

DLL には、次の 3 つのメソッドを実装するクラスが含まれている必要があります。

  • InitiateCall: このメソッドは、MIM サービスによって呼び出されます。 このサービスにより、電話番号と要求 ID がパラメーターとして渡されます。 このメソッドでは、PendingSuccess または FailedPhoneCallStatus 値を返す必要があります。
  • GetCallStatus: initiateCall に対する事前呼び出しで Pending が返された場合、このメソッドが MIM サービスによって呼び出されます。 このメソッドは、PendingSuccess または FailedPhoneCallStatus 値も返します。
  • GetFailureMessage: InitiateCall または GetCallStatus の事前呼び出しで Failed が返された場合、このメソッドが MIM サービスによって呼び出されます。 このメソッドでは、診断メッセージが返されます。

これらのメソッドの実装は、スレッド セーフである必要があります。さらに、以前の GetCallStatus 呼び出しと GetFailureMessage 同じスレッドによって呼び出 InitiateCallされることを前提とした実装である必要があります。

DLL を C:\Program Files\Microsoft Forefront Identity Manager\2010\Service\ ディレクトリに格納します。

Visual Studio 2010 以降を使用してコンパイルできるサンプル コード。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.IdentityManagement.PhoneServiceProvider;

namespace CustomPhoneGate
{
    public class CustomPhoneGate: IPhoneServiceProvider
    {
        string path = @"c:\Test\phone.txt";
        public PhoneCallStatus GetCallStatus(string callId)
        {
            int res = 2;
            foreach (string line in File.ReadAllLines(path))
            {
                var info = line.Split(new char[] { ';' });
                if (string.Compare(info[0], callId) == 0)
                {
                    if (info.Length > 2)
                    {
                        bool b = Int32.TryParse(info[2], out res);
                        if (!b)
                        {
                            res = 2;
                        }
                    }
                    break;
                }
            }
            switch(res)
            {
                case 0:
                    return PhoneCallStatus.Pending;
                case 1:
                    return PhoneCallStatus.Success;
                case 2:
                    return PhoneCallStatus.Failed;
                default:
                    return PhoneCallStatus.Failed;
            }       
        }
        public string GetFailureMessage(string callId)
        {
            string res = "Call ID is not found";
            foreach (string line in File.ReadAllLines(path))
            {
                var info = line.Split(new char[] { ';' });
                if (string.Compare(info[0], callId) == 0)
                {
                    if (info.Length > 2)
                    {
                        res = info[3];
                    }
                    else
                    {
                        res = "Description is not found";
                    }
                    break;
                }
            }
            return res;            
        }
        
        public PhoneCallStatus InitiateCall(string phoneNumber, Guid requestId, Dictionary<string,object> deliveryAttributes)
        {
            // Here should be some logic for performing voice call
            // For testing purposes we just write details in file             
            string info = string.Format("{0};{1};{2};{3}", requestId, phoneNumber, 0, string.Empty);
            using (StreamWriter sw = File.AppendText(path))
            {
                sw.WriteLine(info);                
            }
            return PhoneCallStatus.Pending;    
        }
    }
}

手順 3: 既存の MfaSettings を保存する

"C:\Program Files\Microsoft Forefront Identity Manager\2010\Service" フォルダーにあるMfaSettings.xmlをバックアップします。

手順 4: MfaSettings.xml ファイルを編集する

次の行を更新するか削除します。

  • 構成が入力されているすべての行を削除/クリアします。

  • カスタムの電話プロバイダーを使用して、次の MfaSettings.xml で次の行を更新するか追加します。
    <CustomPhoneProvider>C:\Program Files\Microsoft Forefront Identity Manager\2010\Service\CustomPhoneGate.dll</CustomPhoneProvider>

手順 5: MIM サービスを再起動する

サービスが再起動されたら、SSPR および PAM を使用して、カスタム ID プロバイダーで機能を検証します。

注意

設定を元に戻すには、MfaSettings.xml を手順 3 のバックアップファイルに置き換えます。

次の手順