6

I am struggling with calling search.asmx service from asp.net page. I've created proxy class using svcutil.exe and run request using following code:

var binding = new BasicHttpBinding();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
binding.Security.Transport.Realm = string.Empty;
binding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Default;
var service = new QueryServiceSoapClient(binding, new EndpointAddress("http://mysite/_vti_bin/search.asmx"));
service.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
var res = service.QueryEx(qXMLString);

Web application is set up using Kerberos authentication, I got exception

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

in method System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication
I've tried set up service.ClientCredentials.Windows.AllowNtlm = true; but error is the same.

What can be the cause of this problem?

Thanks in advance.

UPD:

I've tried above code to run in a console app, and all working fine, exception is thrown form asp.net codebehind only.

UPD2:

User which run this code has appropriate permissions in SharePoint (actually console app runs under the same user as codebehind).

4
  • Did you tried debugging it as to see if you are passing right credentials Commented Jan 20, 2013 at 20:15
  • How can I check it? Commented Jan 21, 2013 at 7:54
  • 1
    AllowNtlm doesn't work anymore they got rid of it, need to allow this in your local policy instead.
    – Hugh Wood
    Commented Jan 21, 2013 at 10:51
  • Kai, I wrote solution and wondering if you have feedback on it? I am using Visual Studio to generate the proxy and then call the asmx service. Commented Jan 24, 2013 at 17:05

3 Answers 3

2
+100

Kai

I have done the solution but it's done the client in the Visual Studio 2012 using Service references. The solution is to make sure that you send a NTLM authentication request.

Here is the complete source code for a console application being done in Visual Studio 2012:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestSearchASMX.SearchServiceRef;

namespace TestSearchASMX
{
    class Program
    {
        static void Main(string[] args)
        {

            QueryServiceSoapClient client = new QueryServiceSoapClient();
            client.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
            client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

            string query = @"<?xml version=""1.0"" encoding=""utf-8""?>
                             <QueryPacket xmlns=""urn:Microsoft.Search.Query"" Revision=""1000"">
                               <Query domain=""QDomain"">
                                  <SupportedFormats>
                                     <Format>
                                        urn:Microsoft.Search.Response.Document.Document
                                     </Format>
                                  </SupportedFormats>
                                  <Context>
                                     <QueryText language=""en-US"" type=""STRING"">test</QueryText>
                                  </Context>
                               </Query>
                            </QueryPacket>";

            string result = client.Query(query.ToString());

        }
    }
}

app.config will look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
              <binding name="QueryServiceSoap">

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

           </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://skvkfm-100-1:46812/_vti_bin/search.asmx"
                binding="basicHttpBinding" bindingConfiguration="QueryServiceSoap"
                contract="SearchServiceRef.QueryServiceSoap" name="QueryServiceSoap" />
        </client>
    </system.serviceModel>
</configuration>

If you're using Visual Studio 2008 then C# code will remain same but app.config will be slightly different to reflect the NTLM request:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="QueryServiceSoap" 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="TransportCredentialOnly">
                        <transport clientCredentialType="Ntlm"/>
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://skvkfm-100-1:46812/_vti_bin/search.asmx"
                binding="basicHttpBinding" bindingConfiguration="QueryServiceSoap"
                contract="ServiceReference1.QueryServiceSoap" name="QueryServiceSoap" />
        </client>
    </system.serviceModel>
</configuration>

here is the outcome of my request:

<ResponsePacket xmlns="urn:Microsoft.Search.Response"><Response domain="QDomain"><Range><StartAt>1</StartAt><Count>10</Count><TotalAvailable>100</TotalAvailable><Results><Document relevance="87307112" xmlns="urn:Microsoft.Search.Response.Document"><Title>Test blogg</Title><Action><LinkUrl size="85948">http://skvkfm-100-1:9899/sites/sitedirectory/UB_bloggtest</LinkUrl></Action><Description /><Date>2013-01-09T18:20:56</Date></Document><Document relevance="86917136" xmlns="urn:Microsoft.Search.Response.Document"><Title>test</Title><Action><LinkUrl size="0" fileExt="aspx">http://skvkfm-100-1:9899/sites/df/Lists/test/AllItems.aspx</LinkUrl></Action><Description /><Date>2013-01-03T12:41:03</Date></Document><Document relevance="75816730" xmlns="urn:Microsoft.Search.Response.Document"><Title>Test blogg - Länkar</Title><Action><LinkUrl size="0" fileExt="aspx">http://skvkfm-100-1:9899/sites/sitedirectory/UB_bloggtest/Lists/Lankar/AllItems.aspx</LinkUrl></Action><Description>I listan Länkar samlar du länkar till webbsidor som är intressanta eller användbara för gruppmedlemmarna.</Description><Date>2011-04-28T12:57:45</Date></Document><Document relevance="74951580" xmlns="urn:Microsoft.Search.Response.Document"><Title>Test blogg - Kategorier</Title><Action><LinkUrl size="0" fileExt="aspx">http://skvkfm-100-1:9899/sites/sitedirectory/UB_bloggtest/Lists/Kategorier/AllCategories.aspx</LinkUrl></Action><Description>Använd listan Kategorier om du vill definiera kategorier för inlägg.</Description><Date>2011-04-28T12:57:46</Date></Document><Document relevance="74940626" xmlns="urn:Microsoft.Search.Response.Document"><Title>Test blogg - Inlägg</Title><Action><LinkUrl size="0" fileExt="aspx">http://skvkfm-100-1:9899/sites/sitedirectory/UB_bloggtest/Lists/Anslag/AllPosts.aspx</LinkUrl></Action><Description>Använd listan Inlägg för inlägg i den här bloggen.</Description><Date>2012-09-20T17:48:27</Date></Document><Document relevance="73484562" xmlns="urn:Microsoft.Search.Response.Document"><Title>Test blogg - Kommentarer</Title><Action><LinkUrl size="0" fileExt="aspx">http://skvkfm-100-1:9899/sites/sitedirectory/UB_bloggtest/Lists/Kommentarer/AllComments.aspx</LinkUrl></Action><Description>I listan Kommentarer lagras kommentarer som har gjorts i inlägg.</Description><Date>2012-09-20T17:48:27</Date></Document><Document relevance="68521602" xmlns="urn:Microsoft.Search.Response.Document"><Title>Webbplatskatalogen</Title><Action><LinkUrl size="430688">http://skvkfm-100-1:9899/sites/sitedirectory</LinkUrl></Action><Description /><Date>2013-01-09T18:20:56</Date></Document><Document relevance="68517432" xmlns="urn:Microsoft.Search.Response.Document"><Title>df</Title><Action><LinkUrl size="98487">http://skvkfm-100-1:9899/sites/df</LinkUrl></Action><Description>df</Description><Date>2013-01-09T18:20:38</Date></Document><Document relevance="66580222" xmlns="urn:Microsoft.Search.Response.Document"><Title>Home - df</Title><Action><LinkUrl size="0" fileExt="aspx">http://skvkfm-100-1:9899/sites/df/default.aspx</LinkUrl></Action><Description /><Date>2013-01-09T18:23:24</Date></Document><Document relevance="65463796" xmlns="urn:Microsoft.Search.Response.Document"><Title>df - How To Use This Library</Title><Action><LinkUrl size="73538" fileExt="aspx">http://skvkfm-100-1:9899/sites/df/SitePages/How To Use This Library.aspx</LinkUrl></Action><Description /><Date>2013-01-03T12:38:23</Date></Document></Results></Range><Status>SUCCESS</Status></Response></ResponsePacket>

Note: Make sure your web application has service application connection with Search Service application. A service application connection associates the service application to Web applications via membership in a service application connection group (also referred to as application proxy group).

Sample Search.asmx url that I used: http://testserver-100-1:46812/_vti_bin/search.asmx

Happy SharePointing!

1

In your Web application's web.config add following tag within <system.web>,

<authentication mode="Windows" />
2
  • I've just check - authentication mode is Windows in web.config, also it has <identity impersonate="true" /> Commented Jan 21, 2013 at 9:48
  • @Kai Is there any chance to view web.config of your web application as to figure out what's or where if anything is missing and also I think you figured out how to debug web services (using console app) Commented Jan 21, 2013 at 21:19
1

have a loook at your web.config:

change the following:

ClientCredentialType=Ntlm

to

clientCredentialType = windows

https://stackoverflow.com/questions/762239/difference-between-clientcredentialtype-windows-and-ntlm

https://stackoverflow.com/questions/2608887/sharepoint-web-services-the-http-request-is-unauthorized-with-client-authenti

EDIT

someone had a similar issue:

The system admin only configured Kerberos for one web application. The web part was querying the WCF service for a different web application which only had NTLM configured.

Why do I get a 401 error when calling a WCF service from a web part?

this also leads me to belive that you must of missed a setting ;)

http://pankajsurti.wordpress.com/2012/05/10/the-http-request-is-unauthorized-with-client-authentication-scheme-anonymous-the-authentication-header-received-from-the-server-was-ntlm/

https://stackoverflow.com/questions/3940703/not-authorized-for-search-asmx-web-service

EDIT|

add the following code to your code:

// ** We need to specify an identity (any identity) in order to get it past .net3.5 sp1
EndpointIdentity epi = EndpointIdentity.CreateUpnIdentity("unknown");
EndpointAddress epa = new EndpointAddress(new Uri(address),epi);

client = new DocumentConverterServiceClient(binding, epa);

client.Open();

SharePoint search web service error (NTLM) when called from HttpHandler

hope it helps :)

8
  • I've already specified credential type using this code: binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows; Commented Jan 21, 2013 at 9:29
  • have you looked at your web.config to see the current security settings? also check that all webapplication settings are correct, i mean is kerbos only for one webapplication? check this out ;) sharepoint.stackexchange.com/questions/5467/…
    – Ali Jafer
    Commented Jan 21, 2013 at 9:46
  • Kerberos is using for all web applications. Which security settings should I check? Commented Jan 21, 2013 at 9:55
  • just a side note before you check all this: have you checked permissions were not granted to "authenticated user" in any of the Sharepoint permission groups? you should add "authenticated user" to the Viewers group. I presume when you ran the code in the console app it was at an admin level and not the same user using the webpart?
    – Ali Jafer
    Commented Jan 21, 2013 at 10:10
  • social.msdn.microsoft.com/Forums/en-GB/…
    – Ali Jafer
    Commented Jan 21, 2013 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.