3

私は初心者です。私をとても混乱させるこの認証設定/バインディングのものを理解するのを手伝ってください。

Win2008のIIS7にC#WCFサービスを展開しています。クライアントはWindowsフォームC#アプリです。クライアントは、WCFサービスが実行されているのと同じサーバーから実行されている場合は問題なく動作しますが、リモートPCからクライアントを実行しようとすると、次の例外が発生します...

System.ServiceModel.Security.SecurityNegotiationException:呼び出し元がサービスによって認証されていません。

これらの問題に関するいくつかの投稿を読みましたが、私の問題は、サービスとクライアントがWindows認証を使用するように構成されているためであることがわかりました。これは、Visual Studioを使用してサービスを作成し、サービス参照を追加するときのデフォルトです。クライアントに。以下は、変更を加える前の、まだWindowsに設定されている(無関係なビットが削除されている)構成です...

Web.Config

<system.web>
    ...
    <authentication mode="Windows"/>
    ...

<system.serviceModel>
    <services>
        <service name="MCLaborServer.LaborService" behaviorConfiguration="MCLaborServer.LaborServiceBehavior">
            <!-- Service Endpoints -->
            <endpoint address="" binding="wsHttpBinding" contract="MCLaborServer.ILaborService">
                <!-- 
          Upon deployment, the following identity element should be removed or replaced to reflect the 
          identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity 
          automatically.
      -->
                <identity>
                    <dns value="localhost"/>
                </identity>
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MCLaborServer.LaborServiceBehavior">
                <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                <serviceMetadata httpGetEnabled="true"/>
                <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

そして、クライアントのApp.Configから...

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_ILaborService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="Message">
                    <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        algorithmSuite="Default" establishSecurityContext="true" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://<myDnsNameGoesHere>/MCLaborServer/LaborService.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ILaborService"
            contract="LaborService.ILaborService" name="WSHttpBinding_ILaborService">
            <identity>
                <dns value="localhost" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

そのため、最初にweb.configで「authenticationmode = "None"」を変更し、クライアントのapp.configで「securitymode = "None"」を設定し、メッセージとトランスポートの両方にclientCredentialType="None"を設定しました。また、web.configとクライアントのapp.configの両方の「identity」セクションをコメントアウトしました。それはそれを完全に壊しました、そして今ローカルで実行しているクライアントは動作さえしません。「リモートサーバーが予期しない応答を返しました:(405)メソッドが許可されていません」というエラーが表示されます。

では、リモートクライアントを使用して接続できるように、セキュリティをオフにするにはどうすればよいですか?ちなみに、IISではアプリケーションの匿名アクセスを有効にしています。

また、SSLを使用したり、費用がかかることを行わずに、インターネット経由でリモートクライアント上で半安全な方法でWebサービス呼び出しを行うことができるように、これを構成するためのベストプラクティスの方法は何ですか。データは機密データではないため、セキュリティについてはそれほど心配していませんが、サーバーが攻撃にさらされていないことを確認したいと思います。

また、Windows認証を使用できることを読み、次のようにコードでクレデンシャルを明示的に指定します。それを行った場合でも、リモートで機能しますか?もしそうなら、それはサーバーの私のWindowsクレデンシャルを安全でない方法でネットワーク経由で送信することになりますか?それで私は自分のクレデンシャルを乗っ取られる可能性がありますか?

SomeService.ServiceClient someService = new SomeService.ServiceClient(); 
someService.ClientCredentials.Windows.ClientCredential.UserName="windowsuseraccountname" 
someService.ClientCredentials.Windows.ClientCredential.Password="windowsuseraccountpassword"

以下の投稿/リンクを読みましたが、まだ混乱しています。助けてくれてありがとう!

WCFエラー:発信者はサービスによって認証されませんでした

「発信者がサービスによって認証されなかった」を修正するにはどうすればよいですか?

http://msdn.microsoft.com/en-us/library/aa291347(v=vs.71).aspx

http://www.devx.com/codemag/Article/33342/1763/page/2

4

2 に答える 2

1

バインディングをbasicHttpBindingに変更し、認証をFormsに変更し、セキュリティをオフにすることで、これを修正しました。

于 2012-06-20T22:50:31.540 に答える
1

ドメイン間で実行されるセキュリティの低いWCFサービスをセットアップするときに、同様の問題が発生しました。最大の問題の1つ(それと呼べる場合)は、WCFがデフォルトで非常に安全になるように構成されていることです。私たちのアプリケーションは完全に安全なネットワーク内にあったので、多くの複雑な証明書を気にする必要はありませんでした。回避策は、暗号化なしでサービスにユーザー名/パスワード認証を使用できるようにするカスタムバインディングを作成することでした。YaronNavehのClearUsernameBinding 基づいて実装しました。それをご覧になることをお勧めします(そしてそれを紹介している彼のブログ投稿をご覧ください)。

WCFバインディングとセキュリティについて学ぶためのいくつかの優れたリソース:

于 2012-06-13T15:53:32.610 に答える