Thursday, March 3, 2011

CRM Discovery service, WCF Client and NTLM Authentication on LAN

First point was how I access the Dynamics CRM 4.0 Discovery Service? Here is the url provided in search engines:

http://[IP:port]/MSCrmServices/2007/ad/crmdiscoveryservice.asmx?WSDL

This is a url that can work on CRM server itself and on intranet.
after adding this service reference in a plain c# project, here is bining information added in config file:

<binding name="CrmDiscoveryServiceSoap" 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="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>

You can see default security mode is none. Let us try to build access this discovery service.
CrmDiscoveryServiceSoapClient discoSvc = new CrmDiscoveryServiceSoapClient();
NetworkCredential crmCredential = new NetworkCredential(User, Password, Domain);
discoSvc.ClientCredentials.Windows.ClientCredential = crmCredential;
discoSvc.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Identification;
           
RetrieveOrganizationsRequest orgrequest = new RetrieveOrganizationsRequest();
RetrieveOrganizationsResponse orgresponse = (RetrieveOrganizationsResponse)discoSvc.Execute(orgrequest);
OrganizationDetail myorg = new OrganizationDetail();
foreach (OrganizationDetail organizationDetail in orgresponse.OrganizationDetails)
{
if (organizationDetail.OrganizationName.Equals(orgname, StringComparison.OrdinalIgnoreCase))
       {
             // ...
        }
 }

I get following exception while execution:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'.
I replaced web.cofg security section, and it worked for me.
<security mode="TransportCredentialOnly">
  <transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
  <message clientCredentialType="UserName" algorithmSuite="Default" />
</security>

No comments:

Post a Comment