次の方法で共有


サービス指向ソリューションでの SSO の効率的な使用

サービス指向ソリューションでは、バックエンド システムの構成値の保存と資格情報の処理にエンタープライズ シングル サインオン (SSO) が使用されます。 待機時間を減らすために、このソリューションでは構成値のローカル キャッシュが使用されます。 キャッシュは 5 分おきに更新されます。

多くのアプリケーションでは、SSO チケットの取得、チケットの引き換え、関連アプリケーションにアクセスするための資格情報の使用をはじめとする SSO 操作をアダプタで処理します。 しかし、サービス指向ソリューションのインライン バージョンはアダプタを使用しないので、 コードから SSO を使用する必要があります。

このトピックでは、ソリューションが使用するキャッシュのメカニズムと、ソリューションのインライン バージョンがコードから SSO を使用する方法について説明します。

構成値のローカル キャッシュ

サービス指向ソリューションでは、 ConfigPropertyBagConfigParameters の 2 つのオブジェクトを使用して構成値を処理します。 ConfigPropertyBag クラスは値を保持し、ConfigParameters クラスでのみ使用されます。 ConfigParameters クラスは、構成パラメーターを取得するためにソリューションの他の部分で使用されます。 どちらのクラスも Microsoft.Samples.BizTalk.WoodgroveBank.ConfigHelper 名前空間にあります。

Note

サービス指向ソリューションではキャッシュ更新間隔が 300 秒 (5 分) に固定されます。 代わりに、キャッシュ更新間隔自体をこのソリューションで構成可能なプロパティにすることができます。 この設定はビジネス プロセス管理ソリューションで行います。 そのソリューションで SSO を処理する方法の詳細については、「 Business Process Management Solution での SSO の効率的な使用」を参照してください。 なお、更新間隔を変更した場合は、以前の間隔で最後にキャッシュが更新された後で変更が有効になります。

ConfigPropertyBag には、次のメソッドがあります。

メソッド 説明
Read 指定したプロパティの値を取得します。
Write 値をプロパティに割り当てます。

クラスは、.NET NameValueCollection のインスタンスを使用して値を保持します。 2 つのアクセスメソッドは、Microsoft.BizTalk.SSOClient.Interop 名前空間から IPropertyBag インターフェイスを実装します。 ConfigPropertyBag クラスは内部クラスであり、ConfigParameters クラスでのみ使用されます。

Note

プロパティ バッグのキー名は大文字と小文字が区別されません。 基になる NameValueCollection では、大文字と小文字を区別しないハッシュと大文字と小文字を区別しない比較が使用されます。

アプリケーションでは 、ConfigParameters クラスを使用して SSO 構成値を処理します。 このクラスには、次のパブリック メソッドと属性が含まれます。

メソッドまたは属性 説明
SSOConfigParameter 構成パラメータを指定する列挙。
GetConfigParameters 特定のパラメータの値を取得するメソッド。 SSOConfigParameter を使用してパラメータを指定します。

ConfigParameters クラスでは、.NET Timer クラスとデリゲート関数を使用して、ConfigPropertyBag の更新を設定します。

private static Timer cacheRefreshTimer;  
private static ISSOConfigStore ssoConfigStore;  
private static ReaderWriterLock syncLock;  
  
// Cache refresh interval in milliseconds  
private const int CacheRefreshInterval = 5 * 60 * 1000;  
private static ConfigPropertyBag ssoPropBag;  
  
static ConfigParameters()  
{  
    ssoConfigStore = new ISSOConfigStore();  
    ssoPropBag = new ConfigPropertyBag();  
    syncLock = new ReaderWriterLock();  
  
    ssoConfigStore.GetConfigInfo(SSO_CONFIG_APP,  
         SSO_IDENTIFIER_NAME, SSOFlag.SSO_FLAG_RUNTIME,  
         ssoPropBag);  
  
    cacheRefreshTimer = new Timer(  
        new TimerCallback(ConfigParameters.cacheRefreshCallback),  
        null, CacheRefreshInterval, CacheRefreshInterval);  
}  

この静的コンストラクタにより静的メンバの変数が初期化されるので、クラスのインスタンスを作成しなくてもクラス メソッドが使用できるようになります。 コンストラクターは、更新と読み取り時に ConfigurationPropertyBag へのアクセスを制御するために使用される SSO 構成ストア (ISSOConfigStore)、構成プロパティ バッグ (ConfigPropertyBag)、同期ロック (ReaderWriterLock) のインスタンスを作成します。 その後、コンストラクターは GetConfigInfo を 使用して SSO 構成値を取得し、それらをプロパティ バッグに格納します。 最後に、コンストラクターは Timer オブジェクトを作成し、指定した間隔の後にデリゲート関数 cacheRefreshCallback を呼び出します。

Timer デリゲート関数は比較的簡単です。

private static void cacheRefreshCallback(object state)  
{  
    // Disable the timer until we are done loading the cache.  
    cacheRefreshTimer.Change(Timeout.Infinite, CacheRefreshInterval);  
  
    // Put the data from SSO in a new property bag so that  
    // we don't have to lock the property bag and block it from being  
    // used. The SSO call is a remote call and may take a while.  
    ConfigPropertyBag propBag2 = new ConfigPropertyBag();  
    ssoConfigStore.GetConfigInfo(SSO_CONFIG_APP,   
        SSO_IDENTIFIER_NAME, SSOFlag.SSO_FLAG_RUNTIME, propBag2);  
  
    // Get a writer lock before updating the cached values.  
    syncLock.AcquireWriterLock(Timeout.Infinite);  
  
    try  
    {  
        ssoPropBag = propBag2;  
    }  
    finally   
    {  
        syncLock.ReleaseWriterLock();  
    }  
    // Enable the timer.  
    cacheRefreshTimer.Change(CacheRefreshInterval,   
        CacheRefreshInterval);  
}  

キャッシュ更新コールバック メソッドは、メソッドが最後まで実行されるように、タイマを無効にします。 また、ロックの使用によってプロパティ バッグへのアクセスを制御します。 ReaderWriterLock は、書き込みよりも読み取りが多い場合に最適な選択肢です。 また、lock syncLock は静的であり、すべてのスレッドが同じ単一インスタンスを共有するクラス レベルで宣言されていることにも注意してください。

コードからの SSO の使用

コードからシングル サインオンを使用する場合、コードはアダプターの役割を担う必要があります。つまり、メッセージから SSO チケットを取得し、チケットを引き換えてバックエンド システムのユーザー名とパスワードを取得し、最後にバックエンド システムを使用します。 サービス指向ソリューションは、PendingTransactionsCaller オブジェクトの GetPendingTransactionsResponse メソッドを使用してこれを行います。

メソッドの内容は次のとおりです。

public static PendingTransactionsResponse GetPendingTransactionsResponse(XLANGMessage requestMsg)  
{  
    try  
    {  
        // Get config parameter values.  
        int ptTimeout = Convert.ToInt32(  
            ConfigParameters.GetConfigParameter(  
                ConfigParameters.  
                    SSOConfigParameter.  
                        PENDING_TRANSACTIONS_INLINE_TIMEOUT  
            )  
        );  
  
        string ptURL = ConfigParameters.GetConfigParameter(  
            ConfigParameters.  
                SSOConfigParameter.  
                    PENDING_TRANSACTIONS_URL  
        );  
        string ssoAffliateApp = ConfigParameters.  
            GetConfigParameter(ConfigParameters.  
                SSOConfigParameter.  
                    PENDING_TRANSACTIONS_SSO_AFFILIATE_APP  
            );  
  
        // Redeem the SSO ticket and get the userid/password to   
        // use to interact with Pending Transaction System.  
  
        // Extract the ticket…  
        string msgTicket = (string)requestMsg.  
            GetPropertyValue(typeof(BTS.SSOTicket));  
  
        // and the user name of the originating user.  
        string originatorSID = (string)requestMsg.  
            GetPropertyValue(  
                typeof(  
                    Microsoft.BizTalk.XLANGs.BTXEngine.OriginatorSID  
                )  
            );  
  
        string pendTransUserName;  
        // Now, redeem the ticket.  
        string[] pendTransCredential =   
            ssoTicket.RedeemTicket(  
                ssoAffliateApp,  
                originatorSID,  
                msgTicket,  
                SSOFlag.SSO_FLAG_NONE,  
                out pendTransUserName  
            );   
  
        PendingTransactionsRequest req =   
            (PendingTransactionsRequest)requestMsg[0].  
                RetrieveAs(  
                    typeof(PendingTransactionsRequest)  
                );  
        PendingTransactionsResponse resp;  
  
        using (PendingTransactionsWebService  
            svc = new PendingTransactionsWebService())  
        {  
            svc.Url = ptURL;  
            svc.Timeout = ptTimeout;  
  
            // The web service uses basic authentication, so we  
            //need to send the user id and password in the request.  
            CredentialCache credCache = new CredentialCache();  
            NetworkCredential credentialToUse =  
                new NetworkCredential(  
                    pendTransUserName, pendTransCredential[0]  
                );  
            credCache.Add(new Uri(svc.Url), "Basic", credentialToUse);  
            svc.Credentials = credCache;  
  
            resp = svc.GetPendingTransactions(req);  
        }  
        return resp;                  
    }  
    catch (System.Net.WebException webEx)  
    {  
        if (webEx.Status == WebExceptionStatus.Timeout)  
        {  
            throw new PendingTransactionsTimeoutException();  
        }  
        else  
        {  
            Trace.WriteLine("Other Net.WebException: "  
                + webEx.ToString()   
                + (null == webEx.InnerException ? "" :  
                     ("Inner Exception: "   
                        + webEx.InnerException.ToString())  
                )  
            );  
            throw;  
        }  
    }  
    catch(System.Exception ex)  
    {  
        Trace.WriteLine("Other Exception: "  
            + ex.ToString()   
            + (null == ex.InnerException ? "" :   
                 ("Inner Exception: "  
                    + ex.InnerException.ToString())  
                  )  
            );  
        throw;  
    }  
}  

このメソッドではまず、バックエンド システムの URL やバックエンド (関連) アプリケーションの名前などの構成情報を取得しています。

チケットを引き換えるために、メソッドはメッセージからチケットと元の要求ユーザー名を抽出する必要があります。 メッセージには、メッセージ コンテキスト プロパティの 1 つである BTS としてチケットが含まれています 。SSOTicket。 詳細については、「UI ガイダンスと開発者 API 名前空間リファレンス」のメッセージ コンテキスト プロパティに関するページを参照してください。 メソッドは、メッセージ コンテキスト プロパティから OriginatorSID も抽出します。 メソッドは、抽出したチケットと発信者の名前を使用して、チケットに対して RedeemTicket メソッドを呼び出し、資格情報を取得します。

残りのコードでは、資格情報の .NET NetworkCredential キャッシュを作成してバックエンド Web サービスを呼び出しています。

Note

ユーザー名とパスワードは SSO からクリアテキストで返されるので、その情報が変数に保持されている時間は最小限に抑える必要があります。 コードでは 、try ブロック内で資格情報変数が宣言されていることに注意してください。 ここで、変数は try ブロックから終了すると有効期限が切れます。

参照

サービス指向ソリューションの実装の重要なポイント