3

私のチームにはかなり大きなアプリケーションがあり、WCFNetTCPベースのサービスを多数含むアプリケーションを開発しています。このシステムが実行されるWindowsサービスは、ローカルアカウントではなく、標準のドメインユーザー(サービスをホストするサーバーの管理者権限を持つ)になります。接続のテスト中に、SSPI呼び出しが失敗するという問題が発生しました。数時間の調査に基づいて、これにより、クライアント構成から次の行が欠落しているという道をたどりました。

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

これを使用する際の問題は、VSまたはsvcutilを使用してこのサービスのクライアント/プロキシを生成しないことです。使用されているプロキシは完全にコードで記述されており、System.ServiceModel.ClientBaseを継承します。このオプションが選択された元々の理由は、フェンスの両側のサービスを通過するまったく同じDataMemberオブジェクトを使用できるようにするためだったと思います。サードパーティのグループはサービスに接続する必要がないため、これは問題ではありませんでした。 。

標準の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>
4

2 に答える 2

7

プロキシを手動で作成しても、構成を構成ファイルに入れることを妨げることはありません。構成で検索するエンドポイントの名前を取得するClientBaseの適切なコンストラクターに委任する、ClientBaseから派生したプロキシクラスの適切なコンストラクターのオーバーロードを公開する必要があります。

もちろん、コードを使用してエンドポイントIDを入力できます。必要なのは、適切な種類のEndpointIdentity派生クラスを作成し、プロキシクラスをインスタンス化するときに使用するEndpointAddressオブジェクトにアタッチすることだけです。このようなもの:

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

MyClient client = new MyClient(epaddr);
于 2009-08-06T12:46:05.760 に答える
1

私はおそらくあなたの質問に直接答えていませんが、フェンスの両側で同じデータメンバーを使用するために、プロキシを手動で作成する必要はありません。svcutilを使用してプロキシを生成し、データメンバーを/rとして持つdllを渡すことです。

例えば

svcutil http://localhost/service/service.svc /r:AssemblyThatHasDataMembers.dll /out:ServiceProxy.cs

これにより、ServiceProxy.csファイルでデータメンバータイプが繰り返されることはありません。wsdl / xsd(真のコントラクトファーストアプローチ)を渡すことでこれを大幅にカスタマイズしたり、/ctなどでコレクションタイプをカスタマイズしたりできます。

これにより、プロキシを手動で作成する時間を大幅に節約できます。同時に、すべてが標準になるため、上記のような問題が発生するのを防ぐことができます。

于 2009-08-05T23:20:28.643 に答える