C#でコンソールアプリを使用してlists.asmxを呼び出し、「httpリクエストはクライアント認証スキーム「ntlm」で許可されていません。サーバーから受信した認証ヘッダーは「Negotiate, NTLM」でした。
環境:
- Kerberos は、Dev ではなく、QA & Production でオンになっています (愚かなことはわかっていますが、どのボックスも管理していません)。
- シェアポイント Web サービスにアクセスして、シェアポイント リスト (lists.asmx) からデータを取得します。
- サーバーはsslを使用しています。
qa 環境で次のようなエラー メッセージが表示されます (スタック トレースは画像にのみ表示されているため、貼り付けることはできません)。
System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
リストへの直接ナビゲーションは、すべてのマシンから正常に機能します。
- コードは、kerberos が有効になっていない開発環境 (サーバー上) で動作します (有効にする必要がありますが、そうではありません。これを変更することはできません)。
- コードは、kerberos が有効になっているデスクトップ マシンからの運用に対して機能します
- コードは、Kerberos が有効になっている QA 環境では機能しません。ここでエラーが発生します
Webサービスを呼び出すには、これを行います(他のセキュリティ関連のコードは関係ありません)
XmlElement element = this.LIstsServiceClient.GetListItems(listName, '', query, fields, '300', null, null);
私のapp.configは次のとおりです
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="clientEndpointBehavior">
<clientCredentials>
<windows allowedImpersonationLevel="Delegation"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="ListsSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="999999999" maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="999999" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
<client>
<endpoint address="https://servername/sitecollectionname/_vti_bin/Lists.asmx"
binding="basicHttpBinding" bindingConfiguration="ListsSoap"
contract="ListsService.ListsSoap" name="ListsSoap" behaviorConfiguration="clientEndpointBehavior" >
<identity>
<servicePrincipalName value="spn" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>