Dynamics CRM 2011 ではユーザを偽装してレコードの操作を行えます。4.0では偽装を行うユーザは Active Directory のセキュリティグループである PrvUserGroup に所属している必要がありました。

2011では2つのうちいずれかの条件を満たすと、ユーザを偽装することができるようになります。

1つは、Dynamics CRM 4.0 と同様にユーザーがPrvUserGroup に所属していること。

もう1つは、Dynamics CRM 2011のセキュリティ権限である、prvActOnBehalfOfAnotherUser を持っていることです。prvActOnBehalfOfAnotherUser は既定のセキュリティロールでは、代理人とシステム管理者が保持しています。下図は代理人のセキュリティロールです。別のユーザーの代わりに操作します に組織全体の権限が設定されていることが確認できます。

偽装に関する全般的な説明は次のURLを参照

Impersonate Another User
http://technet.microsoft.com/en-us/library/gg334744.aspx
もう一方のユーザーの偽装
http://technet.microsoft.com/ja-jp/library/gg334744.aspx

今回取り扱っていない、プラグインの偽装は注意が必要です。次のURLを参照ください。

Impersonation in Plug-ins
http://msdn.microsoft.com/en-us/library/gg309416.aspx
プラグインの偽装
http://msdn.microsoft.com/ja-jp/library/gg309416.aspx

今回は、偽装を行うサンプルと、 Dynamics CRM のユーザが偽装をした場合と、Dynamics CRM のユーザではないが、PrvUserGroup セキュリティグループに所属しているユーザが偽装を行ってレコードを作成した場合に作成者(代理),修正者(代理) がどのようになるかを記載します。

今回の動作確認は次の環境で行っています。

  • Windows Server 2008 R2 上に構築した Dynamics CRM 2011 UR 5 オールインワン環境
  • Visual Studio 2010 Professional SP1

1. 偽装を行うサンプルプログラム

Visual Studio 2010 を起動して、コンソールプログラムを作成します。必要なDLLの参照設定とターゲットフレームワークの設定を行います。方法は[Dynamics CRM 2011]Early Bound なエンティティクラスを使用したレコードのCRUD操作 を参照。

サンプルプログラムは次の通りです。事前バインドされたクラスで取引先担当者レコードを作成しています。偽装するには、 OrganizationServiceProxy.CallerId に偽装先のユーザのGUIDを設定します。サンプルでは偽装するユーザーのGUIDを固定で設定しています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Handcraft.Xrm.Client;

namespace ImpersonateSample01
{
    class Program
    {
        static void Main(string[] args)
        {
            using (OrganizationServiceProxy proxy = GetOrganizationService("crmsvr01", "org01"))
            {
                try
                {
                    proxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
                    proxy.CallerId = Guid.Parse("2F4DC458-50FA-E011-85FA-00155D0A0B14"); // 偽装するユーザー

                    XrmContext context = new XrmContext(proxy);

                    Contact contact = new Contact()
                    {
                        FirstName = "名前テスト",
                        LastName = "姓テスト"
                    };
                    context.AddObject(contact);
                    context.SaveChanges();
                }
                catch (TimeoutException)
                {
                }
                catch (FaultException<OrganizationServiceFault>)
                {
                }
                catch (FaultException)
                {
                }
                catch (Exception)
                {
                }
            }

        }

        /// <summary>     
        /// Crm On-Premise に接続する     
        /// </summary>     
        /// <param name="server">サーバー名</param>     
        /// <param name="orgname">組織名</param>     
        /// <returns>OrganizationServiceProxy のインスタンス</returns>     
        public static OrganizationServiceProxy GetOrganizationService(string server, string orgname)
        {
            string endpointaddress = string.Format("http://{0}/{1}/XRMServices/2011/Organization.svc", server, orgname);
            OrganizationServiceProxy organizationService = new OrganizationServiceProxy(new Uri(endpointaddress), null,
                new System.ServiceModel.Description.ClientCredentials(), null);

            return organizationService;
        }  
    }
}

2.実行結果

下図に処理結果を掲載します。1行目は、システム管理者のセキュリティロール(代理人のセキュリティロールと同様にprvActOnBehalfOfAnotherUser 特権を持ちます)を持つユーザでプログラムを実行した場合の結果が1行目のレコードです。作成者(代理),修正者(代理) に偽装を行ったユーザが設定されています。作成者、修正者は偽装されたユーザになっています。2行目はDynamics CRM にライセンスされたユーザではなく、PrvUserGroup セキュリティーグループに所属しているユーザでプログラムを実行した場合の結果です。作成者(代理), 修正者(代理) の属性は未設定になります。

3. まとめ

説明は以上です。間違いなどありましたらご連絡ください。偽装設定と、レコード作成日(overriddencreatedon) を組み合わせると、多システムからの移行で作成者と作成日を維持して移行できるようになるんだなぁと思いました。修正者は偽装されたユーザ、修正日はデータの移行日になってしまいますが。