9

私は多数のmsdnの記事とcodeplexガイダンスに従いましたが、WCFをKerberos認証と委任で動作させることができず、少し助けていただければ幸いです。

設定

リモートマシンのIISWebサイトにWCFサービスがあります

  • Windows2003R2上のIIS6.0-SP2
  • マシンのSPNが追加されました(http / myserver && http / myserver:8080)
  • IISアプリプール用にADアカウントが作成されました
  • ADアカウントには、(Kerberosの場合)委任を許可する設定があり、trueに設定されています

私は8080でBrianBoothのデバッグサイトを使用していますが、このサイトはKerberos委任のすべての要件に合格しています。デバッグIISサイトでは、匿名認証がオフになっており、統合Windows認証がオンになっています。

これらの設定を、WCFサービスをホストしているサイトにミラーリングしました。

Webサービス-Web構成(オリジナル)

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WsHttpBindingConfig">
                <security>
                    <message negotiateServiceCredential="true" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings> 
    <services>
        <service behaviorConfiguration="ServiceBehavior" name="Service">    
            <endpoint address="" 
                binding="wsHttpBinding" 
                bindingConfiguration="WsHttpBindingConfig" 
                contract="IService">    
                <identity>    
                    <servicePrincipalName value="http/myserver" />    
                    <dns value="" />    
                </identity>    
            </endpoint>    
            <endpoint address="mex" 
                binding="mexHttpBinding" 
                contract="IMetadataExchange" />    
        </service>    
    </services>    
    <behaviors>    
        <serviceBehaviors>    
            <behavior name="ServiceBehavior">    
                <serviceMetadata httpGetEnabled="true"/>    
                <serviceDebug includeExceptionDetailInFaults="true"/>    
                <serviceAuthorization 
                    impersonateCallerForAllOperations="true" />    
            </behavior>    
        </serviceBehaviors>    
    </behaviors>    
</system.serviceModel>

Webサービス-Webメソッド

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetCurrentUserName()
{
    string name = WindowsIdentity.GetCurrent().Name;
    return name;
}

クライアントアプリ-アプリ構成

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IService" 
                ... />
                ...
                <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://myserver/Service.svc" 
            binding="wsHttpBinding" 
            bindingConfiguration="WSHttpBinding_IService"
            contract="KerberosService.IService" 
            name="WSHttpBinding_IService">
            <identity>
                <servicePrincipalName value="http/myserver" />
            </identity>
        </endpoint>
     </client>
</system.serviceModel>

アプリケーションエラー

テストアプリケーションであるWinFormsアプリがWebメソッドを呼び出そうとすると、次のエラーが発生します。

「HTTP要求はクライアント認証スキーム「匿名」で許可されていません。サーバーから受信した認証ヘッダーは「Negotiate、NTLM」でした。」

イベントログ

次のエラーがイベントログにあります。

例外:System.ServiceModel.ServiceActivationException:コンパイル中の例外のため、サービス'/Service.svc'をアクティブ化できません。例外メッセージは次のとおりです。このサービスのセキュリティ設定には「匿名」認証が必要ですが、このサービスをホストするIISアプリケーションでは有効になっていません。

わかりません。このサービスの要点は、匿名認証を許可しないことです。すべてのユーザー/要求は、Kerberosチケットを使用して認証され、他のマシンに渡される必要があります。

Kerberos認証と委任のためにこのWCFサービスをどのように構成する必要がありますか?

リビジョン1

このSOの質問を読んだ後、メタデータエンドポイントを削除しました。これは問題を解決していません。

リビジョン2

さらに調査した後、wsHttpBindingをbasicHttpBindingに変更することを提案するいくつかの投稿を見つけました。web.configのその部分への変更は以下に含まれており、サービスエンドポイントはそのバインディングを参照するように更新されています。

Webサービス-Web構成(改訂)

<basicHttpBinding>
    <binding name="basicBindingConfig">
        <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Windows" 
                proxyCredentialType="Windows" 
                realm="" />
        </security>
    </binding>
</basicHttpBinding>

クライアントアプリ-アプリ構成(改訂)

<!-- ... -->
<security mode="TransportCredentialOnly">
    <transport clientCredentialType="Windows" 
        proxyCredentialType="Windows"
        realm="" />
    <message clientCredentialType="UserName" 
        algorithmSuite="Default" />
</security>
<!-- ... -->

エラー(改訂)

現在のエラーには、Kerberos認証ヘッダーが含まれているようです。

HTTPリクエストは、クライアント認証スキーム「ネゴシエート」では許可されていません。サーバーから受信した認証ヘッダーは'NegotiateSOMEHUGESCARYKEYHERE

4

4 に答える 4

7

私にとって、現在のセットアップは機能します:

サーバー上:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
      <binding name="wsHttpBindingConf" useDefaultWebProxy="true"/>
    </wsHttpBinding>
  </bindings>

  <services>
    <service behaviorConfiguration="returnFaults" name="Epze.BusinessLayer.ZeitManager">
        <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBindingConf" contract="Epze.Contract.IZeitManager"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
    </service>
  </services>

  <behaviors>
    <serviceBehaviors>
        <behavior name="returnFaults">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
            <serviceAuthorization impersonateCallerForAllOperations="true"/>
        </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

WCF のすべてのメソッドに次の属性を設定します。

[OperationBehavior(Impersonation = ImpersonationOption.Required)]

クライアントで:

<system.serviceModel>
  <bindings>
    <wsHttpBinding>
        <binding name="WSHttpBinding_IZeitManager" 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>

  <behaviors>
    <endpointBehaviors>
        <behavior name="Delegation">
        <clientCredentials>
            <windows allowedImpersonationLevel="Delegation" />
        </clientCredentials>
        </behavior>
    </endpointBehaviors>
  </behaviors>        

  <client>
    <endpoint address="http://server.mydomain.net/ePZEsvc/ZeitManager.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IZeitManager" 
              contract="External.Epze.IZeitManager" name="WSHttpBinding_IZeitManager" behaviorConfiguration="Delegation">
        <identity>
            <servicePrincipalName value="HOST/localhost"/>
        </identity>                      
    </endpoint>
  </client>
</system.serviceModel>

HTH、スヴェン

于 2009-09-10T09:18:12.733 に答える
3

私が気づいたこと: クライアントとサーバーの構成がセキュリティモードに同意していないようです。

元のセクションで<security>.....は、web.config (mode="message" を省略) と<security mode="Message">クライアント側にあります。

編集後、クライアント側は変更されていないようですが、サーバー (web.config) には<security mode="TransportCredentialOnly">.

問題は、クライアントと呼び出されるサーバーとの間のネットワーク レッグが 1 つだけであることを保証できるかどうかです。つまり、これは企業のファイアウォールの背後にありますか? <security mode="Transport">その場合、両端で netTcp バインディングを使用することをお勧めします。

そうでない場合は、wsHttpBinding (より多くのセキュリティと信頼性の機能をサポートしますが、遅くて "重い") または basicHttpBinding のどちらでも問題ありません。その場合、<security mode="Message">両端で使用し、証明書を使用してサービスを認証する必要があります (サービスとクライアントが暗号化に使用する共通の「秘密」を持つようにするため)。

最初は偽装の部分を省略して、サービスとクライアントの間の基本的な通信と相互認証を最初に実行します。これが整ったら、偽装ビットの追加を開始できます。いつでも機能する既知の構成にフォールバックします。

David Sackstein は、業界の第一人者である Juval Lowy が (プログラミング WCFの本である WCF Bible で) 最も一般的で最も有用であると特定した 5 つのセキュリティ シナリオを説明する素晴らしい一連のブログ投稿を行っています。微調整したいパラメータ。それらの 1 つは、サービスが外向きである場合に、おそらくここで適用される「インターネット」シナリオです。

マルク

于 2009-08-18T20:49:37.950 に答える
2

クライアント設定で behaviorConfiguration を指定する必要があります。SVCUtil は自動生成されません。これで問題が解決し、Kerberos を正常に使用できるようになりました。ミッションだったのに!

<client>           
    <endpoint address="..."               
    binding="customBinding" bindingConfiguration="..."               
    contract="..." name="..."  behaviorConfiguration="ImpersonationBehavior" />                 
    </client>         
    <behaviors>
         <endpointBehaviors>            
         <behavior name="ImpersonationBehavior">               
              <clientCredentials>                 
              <windows allowedImpersonationLevel="Impersonation"/>                      </clientCredentials>             
    </behavior>                       
    </endpointBehaviors>                   
    </behaviors> 
于 2011-06-14T15:34:51.930 に答える
1

初期構成を試して、IIS を匿名に設定し、同時に Windows 認証を設定する必要があります。その理由は、wsHttpBinding を使用している場合、デフォルトのセキュリティはメッセージ セキュリティであり、https を実行する場合を除き、トランスポート セキュリティは定義されていません。 . SO Clr は、IIS で匿名認証をオンにする必要があると述べています。

于 2010-11-17T02:29:18.887 に答える