WCF:認証に失敗したため、セキュリティトークンの要求を満たせませんでした
-
08-07-2019 - |
質問
同じマシン上に2つのWCFサービスがあります。 1つは発行者で、もう1つはリスナーです。
パブリッシャーは、エンドポイントに基づいてプロキシを動的に作成しています。次のようなコードでプロキシを構成しています:
WSHttpBinding binding = new WSHttpBinding(SecurityMode.Message, true);
binding.Security.Message.NegotiateServiceCredential = true;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;
binding.Security.Message.EstablishSecurityContext = true;
binding.ReliableSession.Enabled = true;
binding.TransactionFlow = true;
return binding;
そして......
Binding binding = GetBindingFromAddress(address);
ChannelFactory<T> factory = new ChannelFactory<T>(binding);
factory.Credentials.UserName.UserName = "an account on the machine";
factory.Credentials.UserName.Password = "a password for that account";
T proxy = factory.CreateChannel(new EndpointAddress(address));
電話をかけると、上記のエラーが表示されます。リスナー構成ファイルは次のとおりです。
<service behaviorConfiguration="MEX Enabled" name="InvoiceSubscriber">
<endpoint binding="wsHttpBinding"
bindingConfiguration="ReliableTransactionalHTTP"
contract="AtlanticBT.SubscriptionService.Contracts.v1.IAtlanticEvents">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<bindings>
<wsHttpBinding>
<binding name="ReliableTransactionalHTTP" transactionFlow="true">
<reliableSession enabled="true"/>
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
サービスをホストするディレクトリですべてのACLをチェックしましたが、それらは正しいようです。 IISセキュリティは、匿名アクセスとWindows認証に設定されます。
コードで資格情報を明示的に設定している場合、リスナーが認証できないのはなぜですか?
解決
まず、このメッセージは通常、マシンが同じドメイン上にないため、Windowsセキュリティを使用して通信できないことを意味します。 2つのサーバーは同じドメインにありますか?
次に、Windowsセキュリティを使用するようにエンドポイントを設定しました。 Windowsセキュリティは、メッセージレベルだけでなく、トランスポートレベルでも使用します。両方ともやり過ぎのように思えますが、おそらくトランスポートをしたいだけです。
3つ目は、設定したすべてが「i Windows認証を使用したい」ということですが、ClientCredentialsのUsernameClientCredentialsプロパティを設定しています。これらのプロパティは、ユーザー名トークンのセキュリティにのみ使用され、Windowsでは使用されません。 Windowsセキュリティは、現在のスレッドのIDを取得して転送します。
Windowsセキュリティを使用することを意図している場合、次のいずれかを行う必要があります。
- サブスクライバーと通信する単一のWindows IDでパブリッシャープロセスを実行します。
- 発行者プロセス内で偽装を使用して、各呼び出しのセキュリティコンテキストを変更します(詳細については、WindowsIdentity.Impersonate )
ユーザー名/パスワードのプロパティは無視されているため、これらを設定することで#2を実行していると思っていても、技術的には#1を実行しています。
最後に、さまざまな種類のWindows認証シナリオ用にバインディングをセットアップする方法に関する優れたドキュメントを次に示します。
これ以外に、あなたからの情報がなくても他に何ができるかわかりません。質問を修正して、さらに情報を提供したり、私の質問の一部に回答したりする場合は、回答をより便利なものにするために喜んで修正します。