While there are many situations in which you can retrieve the error message 401: Unauthorized, there are some more difficult to find than others. Of course you have After you have checked the basic settings including:
- Are the default credentials used
- Does the user have an account in CRM
- Does the user have enough priviledges in CRM
- Is Windows Authentication enabled for the CRM website
- Is anonymous access disabled for the CRM website
If these settings do not solve the issue, then it's getting intereseting. One of the reasons I have experienced, has to do with two steps. In the first step, I've been using the CrmDiscoveryService to find the url's for the CrmService as well as the CrmMetadataService. The second step was using SPN's to allow the server to pass on the kerberos ticket to the server, even though it is a single server install.
Let me get a bit more in detail. The code which I used for the first step is:
CrmDiscoveryService disco = new CrmDiscoveryService();
disco.Credentials = cred;
disco.Url = server + "/MSCRMServices/2007/AD/CrmDiscoveryService.asmx";
RetrieveOrganizationsRequest orgRequest = new RetrieveOrganizationsRequest();
RetrieveOrganizationsResponse orgResponse = (RetrieveOrganizationsResponse)disco.Execute(orgRequest);
foreach (OrganizationDetail orgdetail in orgResponse.OrganizationDetails)
if (orgdetail.OrganizationName == org)
This returns the CrmServiceUrl. Apparently the URL for the web service can have different servername than the url you have used in the code for accessing the CrmDiscoveryService. In my particular example there was the servername (srv-crm01), a dns name (crm) and of course the localhost that could be used to access the server. For accessing the CrmDiscoveryService the dns name was used. The service did return the servername as url for the crm web service.
With the help of a system engineer we found out that this server did have kerberos as authentication method specified. In the list of service principal names (SPN's) the servername was not listed for the http protocol. After this has been added for the servername as well as the fully qualified domain name, the error was gone. To add the SPN's execute the following commands:
setspn -A http/servername
setspn -A http/servername.fullyqualified.name
Don't forget to change the servername and servername.fullyqualified.name to the correct values of your environment.
If you happen to have the same error but find another solution, please share this by adding a comment to help your peers.