在WCF服务中模拟并传播到COM对象

时间:2010-09-07 00:15:08

标签: c# wcf com impersonation

我正在尝试创建一个WCF服务来公开某些服务。在其中一个合同中,我必须模仿另一个用户并调用COM对象。我知道如果我想将模拟传播到COM对象中,我应该在任何编组之前调用CoInitializaSecurity。

int result = CoInitializeSecurity(IntPtr.Zero, -1,
 IntPtr.Zero, IntPtr.Zero,
            RpcAuthnLevel.Connect, RpcImpLevel.Impersonate,
            IntPtr.Zero, EoAuthnCap.DynamicCloaking, IntPtr.Zero);

但它返回80010119,这意味着RPC_E_TOO_LATE。

我知道这意味着已经调用了CoInitializeSecurity。但我想把这个函数称为我合同中的第一条指令。我甚至在服务的构造函数中尝试调用CoInitializeSecurity,但它返回相同的错误。 这意味着内置代码的WCF包含CoInitializeSecurity,我无法再次运行此功能。

我想调用一个com对象,我想让com对象与C#中的模拟用户一起工作,但如果我在调用CoInitializeSecurity方面成功,则意味着COM对象不会被模拟用户运行。


刚刚回复@Remus Rusanu

我已经创建了一个服务合同,如下面的

   [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string GetData()
    {
        MyComClass comObj = new MyComClass();
        string ComUser = comObj.GetLogOnUser();
        return System.Security.Principal.WindowsIdentity.GetCurrent().Name + " " + ComUser;
    }

在客户端我通过所需的凭证调用此服务

    ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
    client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
    client.ClientCredentials.Windows.ClientCredential.Domain = "Domain";
    client.ClientCredentials.Windows.ClientCredential.UserName = "DomainUser";
    client.ClientCredentials.Windows.ClientCredential.Password = "passw0rd";
    string str = client.GetData();

结果是

DOMAIN \ DomainUser DOMAIN \ CurrentUser

这意味着WCF已经模拟到DomainUser,但COM对象内部仍在使用以前的用户。

1 个答案:

答案 0 :(得分:1)

托管主机已经为您初始化COM。您不必重新初始化线程COM安全性。只需在WCF中模拟(例如,通过[OperationBehavior(Impersonation=ImpersonationOption.Required)])并使COM对象实例化,它将在模拟的上下文中发生。并非如果COM对象是远程的,则会发生约束委派,并且必须为受约束的委派配置WCF主机进程。

请参阅How to: Impersonate a Client on a ServiceDelegation and Impersonation with WCFEnabling Delegated Authentication