web-dev-qa-db-ja.com

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

SOにこれに似た多くの質問があることは知っていますが、この特定の問題については見つかりませんでした。

まず、いくつかのポイント:

  • Sharepointサーバー上で制御なしがあります。 IIS設定。
  • IISサーバーのバージョンはIIS 7.0。
  • Sharepointサーバーは、NTLMを介した要求を予測しています。
  • Sharepointサーバーは、クライアントコンピューターと同じドメインにあります。
  • .NET Framework 3.5、Visual Studio 2008を使用しています

Sharepoint Webサービスを使用してSharepointデータを操作する簡単なコンソールアプリを作成しようとしています。サービスリファレンスを追加しました。app.configは次のとおりです。

<system.serviceModel>
    <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="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="Transport">
                    <transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://subdomain.companysite.com/subsite/_vti_bin/Lists.asmx"
            binding="basicHttpBinding" bindingConfiguration="ListsSoap"
            contract="ServiceReference1.ListsSoap" name="ListsSoap" />
    </client>
</system.serviceModel>

これは私のコードです:

static void Main(string[] args)
{
    using (var client = new ListsSoapClient())
    {
        client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("username", "password", "domain");
        client.GetListCollection();
    }
}

GetListCollection()を呼び出すと、次のMessageSecurityExceptionがスローされます。

The HTTP request is unauthorized with client authentication scheme 'Ntlm'.
The authentication header received from the server was 'NTLM'.

内部WebExceptionの場合:

"The remote server returned an error: (401) Unauthorized."

適切に認証しようとするために、さまざまなバインディングとさまざまなコード調整を試しましたが、役に立ちませんでした。以下にリストします。


次の手順を試しました。

クライアントを作成する前にネイティブのWin32 Impersonatorを使用

using (new Impersonator.Impersonator("username", "password", "domain"))
using (var client = new ListsSoapClient())
{
    client.ClientCredentials.Windows.ClientCredential = new NetworkCredential("dpincas", "password", "domain");
    client.GetListCollection();
}

これにより、同じエラーメッセージが生成されました。


クライアント資格情報のTokenImpersonationLevelの設定

using (var client = new ListsSoapClient())
{
    client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
    client.GetListCollection();
}

これにより、同じエラーメッセージが生成されました。


セキュリティモード= TransportCredentialOnlyを使用

<security mode="TransportCredentialOnly">
    <transport clientCredentialType="Ntlm" />
</security>

これにより、異なるエラーメッセージが表示されました。

The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: via

ただし、httpsを使用する必要があるため、URIスキームを変更できません。


私は覚えていない他の組み合わせをいくつか試しましたが、私がするときにそれらを投稿します。私は本当にここで終わりに近づいています。 Googleには「Kerberosに切り替える」というリンクがたくさんありますが、私のサーバーは「ネゴシエート」ではなくNTLMのみを受け入れているようです(Kerberosを探している場合のように)、それは残念ながらオプションではありません。

そこに何か助けがありますか?

49
Pandincus

たくさんの試行錯誤の後、サーバーの人と話す機会を待っている間、停滞期間が続き、ついに彼らと問題について話し合う機会があり、彼らが私たちのSharepoint認証を切り替えることを気にしないかどうか尋ねましたKerberosに。

驚いたことに、彼らはこれは問題ではなく、実際には簡単だと言っていました。 Kerberosを有効にしましたそして、app.configを次のように変更しました。

<security mode="Transport">
    <transport clientCredentialType="Windows" />
</security>

参考までに、app.configのserviceModelエントリ全体は次のようになります。

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="TestServerReference" closeTimeout="00:01:00" openTimeout="00:01:00"
             receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
             bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
             maxBufferSize="2000000" maxBufferPoolSize="2000000" maxReceivedMessageSize="2000000"
             messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
             useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                 maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="Transport">
                    <transport clientCredentialType="Windows" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="https://path/to/site/_vti_bin/Lists.asmx"
         binding="basicHttpBinding" bindingConfiguration="TestServerReference"
         contract="TestServerReference.ListsSoap" name="TestServerReference" />
    </client>
</system.serviceModel>

この後、すべてが魅力のように機能しました。 Sharepoint Webサービスを(ついに!)利用できるようになりました。したがって、他の誰かがSharepoint WebサービスをNTLMで動作させることができない場合は、sysadminにKerberosに切り替えるよう説得できるかどうかを確認してください。

8
Pandincus

Visual Studio 2005

  1. Visual Studioで新しいコンソールアプリケーションプロジェクトを作成する
  2. Lists.asmx Webサービスに「Web参照」を追加します。
    • URLはおそらくhttp://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
    • Web参照に名前を付けました:ListsWebService
  3. Program.csにコードを記述します(ここに問題リストがあります)

これがコードです。

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace WebServicesConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ListsWebService.Lists listsWebSvc = new WebServicesConsoleApp.ListsWebService.Lists();
                listsWebSvc.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
                listsWebSvc.Url = "http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx";
                XmlNode node = listsWebSvc.GetList("Issues");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

Visual Studio 2008

  1. Visual Studioで新しいコンソールアプリケーションプロジェクトを作成する
  2. [参照]を右クリックし、[サービス参照を追加]
  3. サーバー上のLists.asmxサービスへのURLを入力してください
    • 例:http://servername/sites/SiteCollection/SubSite/_vti_bin/Lists.asmx
  4. [Go]をクリックします
  5. OKをクリック
  6. 次のコードを変更します。

App.configファイルを次から変更します。

<security mode="None">
    <transport clientCredentialType="None" proxyCredentialType="None"
        realm="" />
    <message clientCredentialType="UserName" algorithmSuite="Default" />
</security>

に:

<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Ntlm"/>
</security>

Program.csファイルを変更し、メイン関数に次のコードを追加します。

ListsSoapClient client = new ListsSoapClient();
client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
XmlElement listCollection = client.GetListCollection();

Usingステートメントを追加します。

using [your app name].ServiceReference1;
using System.Xml;

参照: http://sharepointmagazine.net/technical/development/writing-caml-queries-for-retrieving-list-items-from-a-sharepoint-list

40
Kit Menke

多くの回答が機能しなかった後、IISサーバーで匿名アクセスが無効になっているときに解決策を見つけました。サーバーはKerberosではなくWindows認証を使用しています。これは このブログ投稿

Web.configは変更されていません。

サーバー側では、ISAPIフォルダーの.SVCファイルはMultipleBaseAddressBasicHttpBindingServiceHostFactoryを使用します

サービスのクラス属性は次のとおりです。

[BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class InvoiceServices : IInvoiceServices
{
...
}

クライアント側では、それを機能させるキーはhttpバインディングセキュリティ属性でした。

EndpointAddress endpoint =
  new EndpointAddress(new Uri("http://SharePointserver/_vti_bin/InvoiceServices.svc"));
BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
InvoiceServicesClient myClient = new InvoiceServicesClient(httpBinding, endpoint);
myClient.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; 

(call service)

これがお役に立てば幸いです!

5
David Anderson

正しく思い出せば、SharePoint WebサービスをVS2K8の「サービスリファレンス」として追加する際にいくつかの問題があります。適切に機能させるには、古いスタイルの「Web参照」として追加する必要があります。

3
Jesse C. Slicer

このツールを使用してSharepointサイトに接続しようとします here 。それが機能する場合、問題がコード/構成にあることを確認できます。それはあなたの問題をすぐには解決しないかもしれませんが、サーバーに何か問題があることを除外します。それが機能しないと仮定すると、私は次を調査します:

  • あなたのユーザーは本当にサイト上で十分な権限を持っていますか?
  • 干渉するプロキシはありますか? (設定はプロキシがあるように見えます。それをバイパスできますか?)

セキュリティモードTransportを使用しても問題はないと思いますが、proxyCredentialType="Ntlm"、多分これはNoneに設定する必要があります。

2
Stefan Egli

この問題は以前にもありました。

client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

呼び出しを行う前に、wcfプロキシに対してこれを行います。

2
bleevo

私はあなたと同じセットアップを持っていますが、これは私にとってはうまくいきます。多分問題は、お使いのmoss設定またはネットワークのどこかにあると思います。

Mossはアプリケーションと同じドメインにあると言いました。ユーザー(マシンにログインしている)でサイトにアクセスできる場合...試しましたか:

client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
2
matt-dot-net

先週まったく同じ問題が発生しました- WCFプログラムは1台のサーバーで奇妙な動作をします-なぜ?

私にとって、解決策はかなり簡単でした。 Sharepointには独自のアクセス許可セットがあります。私のクライアントは、Sharepointの管理パネルからWebサービスへのアクセスを明示的に与えられていないユーザーとしてログオンしようとしました。

Sharepointのホワイトリストにユーザーを追加し、バングしました-うまくいきました。

それが問題ではない場合でも、注意してください

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

単に許可がないという意味(英語)。あなたのプロトコルはおそらく正しいです-あなたのユーザーには許可がありません。

2
diadem

これを試して

<client>
  <endpoint>
    <identity>
      <servicePrincipalName value="" />
    </identity>
  </endpoint>
</client>

ウェブファームで作業しているときにこのエラーが発生したことがありますが、これで修正されました。

0
Forrest Marvez

この問題は私たちにとってさらに奇妙でした。 SOAP呼び出しを行う前に、以前にブラウザから共有サイトにアクセスしたことがあれば、すべてが機能しました。ただし、最初にSOAP d上記のエラーをスローします。

クライアントに共有ポイント証明書をインストールし、ローカルイントラネットサイトにドメインを追加することにより、この問題を解決できました。

0
Glaucon