2

ローカルで実行されているWCFサービスと、リモートで実行されているクライアントがあります。両側のバインディングを次のように一致させました。

<binding name="TcpBindingConfiguration_2">
  <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
  <security mode="Transport">
    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
    <message clientCredentialType="Windows"/>
  </security>
</binding>

Thread.CurrentPrincipal.Identity.Name、ServiceSecurityContext.Current.WindowsIdentity.Name、およびOperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name(使用可能な場合)を返すだけのダミーメソッドセットアップがあります。

サーバーと同じマシンでクライアントを実行している場合、トランスポートモードは問題なく機能し、3つのID名すべてを使用できます。ただし、リモートホスト(同じドメインと異なるドメインの両方のホストでテスト済み)からローカルマシンに接続すると、「サーバーがクライアントの資格情報を拒否しました」という恐ろしいメッセージが表示されます。

バインディングを次のように変更した場合:

<binding name="TcpBindingConfiguration_1">
  <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
  <security mode="None"/>
</binding>

接続が確立され、ダミーメソッドは名前を返しません(私が想像するように)。

誰かがnet.tcpバインディングを使用して、異なるホスト(場合によっては異なる信頼されたドメイン)間でWindows認証を有効にする構成を共有できますか?セキュリティモードを[なし]に設定すると言っている例をたくさん見てきましたが、これはすべて問題ありませんが、誰が電話をかけているのかを特定したいと思います。

では、次は何ですか?mode = "Transport"を機能させますか?mode = "None"を使用して、他のタイプの承認を実装しますか?Windows認証を正常に使用する別のバインディングに変更しますか?

これが他の場所で回答されている場合はお詫びします。私はそれが決定的に答えられている場所を見つけることができません。

更新:これは、クライアントの作成に現在使用しているコードです。

var endPointAddress = "net.tcp://" + remoteHost + ":8092/Marc/WcfService";
EndpointAddress address = new EndpointAddress(new Uri(endPointAddress), EndpointIdentity.CreateSpnIdentity("AppName/" + remoteHost), new AddressHeaderCollection());
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Transport;
binding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign;

using (var remoteService = new RemoteService.GuestServiceClient(binding, address))
{
    try
    {
        MessageBox.Show(remoteService.Hello("Marc"));
        remoteService.Close();
    }
    catch (Exception ex)
    {
        remoteService.Abort();
        MessageBox.Show("Error occurred:\n\n" + ex.Source + "\n\n" + ex.Message, "Could not connect to " + remoteHost, MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

remoteHostはリモートマシンのIPアドレスに設定されています。

チャネルやプロキシなどを使用する必要がありますか?他の場所でそうする他のコードを見たことがありますが、GuestServiceClient()のこの単純なインスタンス化は(少なくともローカルでは)機能しているようです。

4

1 に答える 1

0

通常、コードで WCF サービスを構成するため、これが構成ファイルにどのように変換されるかわかりません。

この数年前の私の調査によると、サービス プリンシパル名 (SPN) をクライアントのエンドポイントの一部として追加する必要があります。サーバー側を変更する必要はありませんでした。

コードでは次のようになります。

string endPointAddress = String.Format("net.tcp://{0}:1111/ServiceName", ServerAddress);
EndpointAddress address = new EndpointAddress(new Uri(endPointAddress), EndpointIdentity.CreateSpnIdentity("AppName/" + ServerAddress), new AddressHeaderCollection());
NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Transport;

2 行目は、接続情報に SPN を追加するものです。EndpointIdentity.CreateSpnIdentity では、文字列は AppName/ServerAddress の形式です。「AppName」の部分は何でもかまいませんが、アプリに固有のものをお勧めします。通常、アドレスには FQDN (host.domain.com) 形式を使用します。

繰り返しますが、これが構成ファイルにどのように変換されるかはわかりません。これが正しい道を歩み始めるのに役立つことを願っています。

于 2012-05-23T12:13:34.010 に答える