WCF代理和userPrincipalName

WCF代理和userPrincipalName,wcf,identity,wcf-security,Wcf,Identity,Wcf Security,我和我的团队正在开发一个相当大的应用程序,其中包含许多基于WCF NetTCP的服务。运行此系统的Windows服务将不是本地帐户,而是标准域用户(在托管该服务的服务器上具有管理员权限)。在测试连接的中间,我遇到了一个SSPI调用失败的问题。基于几个小时的研究,这导致我在客户端配置中遗漏了以下行: <identity> <userPrincipalName value="MACHINE\user" /> </identity> 使用它的问题是我

我和我的团队正在开发一个相当大的应用程序,其中包含许多基于WCF NetTCP的服务。运行此系统的Windows服务将不是本地帐户,而是标准域用户(在托管该服务的服务器上具有管理员权限)。在测试连接的中间,我遇到了一个SSPI调用失败的问题。基于几个小时的研究,这导致我在客户端配置中遗漏了以下行:

<identity>
     <userPrincipalName value="MACHINE\user" />
</identity>

使用它的问题是我没有使用VS或svcutil为此服务生成客户端/代理-使用的代理完全是用代码编写的,它们继承System.ServiceModel.ClientBase。我认为选择此选项的最初原因是,我们可以使用完全相同的DataMember对象,这些对象通过围栏两侧的服务-第三方组不需要连接到我们的服务,因此这不是问题

当我在standard system.serviceModel配置部分中没有指定端点时,有人知道我在客户端(代码或通过配置)中设置userPrincipalName的方法吗

以下是我的客户端web.config的外观,以供参考:

    <system.serviceModel>
    <diagnostics>
        <messageLogging logEntireMessage="true" logMalformedMessages="true"
         logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
    </diagnostics>
    <behaviors>
        <serviceBehaviors>
            <behavior name="includeExceptions">
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <netTcpBinding>
            <binding name="NetTcpBinding_Default" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="Infinite" sendTimeout="01:00:00" portSharingEnabled="true" transferMode="Buffered" maxReceivedMessageSize="2147483647">
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                <security mode="Transport">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
                </security>
            </binding>
        </netTcpBinding>
    </bindings>

</system.serviceModel>

虽然我可能没有直接回答您的问题,但要在围栏两侧使用相同的datamember,您不需要手动创建代理。您要做的是,使用svcuti生成代理,并传入datamember为/r的dll

e、 g

这样,数据成员类型就不会在ServiceProxy.cs文件中重复。您可以通过传递wsdl/xsd(真正的契约优先方法)、使用/ct定制collectiontypes等方式对此进行广泛定制


这将节省您手工制作代理的许多小时,同时避免您可能遇到的上述问题,因为所有内容都将成为库存标准。

手动创建代理不会妨碍您将配置放入配置文件中;您只需要在ClientBase派生的代理类中公开正确的构造函数重载,该类将委托给使用端点名称的in-ClientBase以在配置中查找

也就是说,您当然可以通过代码填写端点标识,您只需要创建正确类型的EndpointIdentity派生类,并将其附加到实例化代理类时使用的EndpointAddress对象。大概是这样的:

EndpointIdentity epid = EndpointIdentity.CreateUpnIdentity("user@domain.fqdn");
EndpointAddress epaddr = new EndpointAddress(uri, epid);

MyClient client = new MyClient(epaddr);

阿什的第一句话让我走上了一条在托马斯尔协助下完成的道路,现在一切都很完美。作为旁注,要创建新的EndpointAddress,必须指定Uri、EndpointIdentity和AddressHeader对象才能使其正常工作。他们的API设置有点混乱(特别是如果您没有正确使用base.New,会出现一些模糊的错误),但所有这些都告诉了它函数。谢谢你的帮助!对于看到这个答案但仍有问题的其他人,我需要使用“域\用户”,这仍然不起作用。我发现我必须使用“user@DOMAIN.local“(或者您的完全限定的Active Directory域名是什么。
EndpointIdentity epid = EndpointIdentity.CreateUpnIdentity("user@domain.fqdn");
EndpointAddress epaddr = new EndpointAddress(uri, epid);

MyClient client = new MyClient(epaddr);