I've looked through a ton of SO articles, and even other sites, but can't seem to get this service working. I have a SOAP service I'm trying to hit and it's configured like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="PROVIDERSSoapBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None" realm="" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://xxx.xx.xx.xxx:9011/provider/services/PROVIDERS"
binding="basicHttpBinding" bindingConfiguration="PROVIDERSSoapBinding"
contract="ServiceReference1.ProviderRemote" name="PROVIDERS" />
</client>
</system.serviceModel>
However, I'm getting the following error when hitting it from my console application:
The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'Negotiate,NTLM'.
Can somebody help me out?
If both your client and service is installed on the same machine, and you are facing this problem with the correct (read: tried and tested elsewhere) client and service configurations, then this might be worth checking.
Check host entries in your host file
%windir%/system32/drivers/etc/hosts
Check to see if you are accessing your web service with a hostname, and that same hostname has been associated with an IP address in the hosts file mentioned above. If yes, NTLM/Windows credentials will NOT be passed from the client to the service as any request for that hostname will be routed again at the machine level.
Try either of the following
Edit: Somehow the above situation is relevant on a load-balanced scenario. However, if removing the host entries is not possible, then disabling loop back check on the machine will help. Refer method 2 in the article https://support.microsoft.com/en-us/kb/896861
You need to set the NTAuthenticationProviders to NTLM
MSDN Article: https://msdn.microsoft.com/en-us/library/ee248703(VS.90).aspx
IIS Command-line (http://msdn.microsoft.com/en-us/library/ms525006(v=vs.90).aspx):
cscript adsutil.vbs set w3svc/WebSiteValueData/root/NTAuthenticationProviders "NTLM"
We encountered this issue and discovered that the error was being thrown when using (IE in our case) the browser logged in as the process account, then changing the session log in through the application (SharePoint). I believe this scenario passes two authentication schemes:
The application hosted an *.asmx web service, that was being called on a load balanced server, initiating a web service call to itself using a WCF-like .NET3.5 binding.
Code that was used to call the web service:
public class WebServiceClient<T> : IDisposable
{
private readonly T _channel;
private readonly IClientChannel _clientChannel;
public WebServiceClient(string url)
: this(url, null)
{
}
/// <summary>
/// Use action to change some of the connection properties before creating the channel
/// </summary>
public WebServiceClient(string url,
Action<CustomBinding, HttpTransportBindingElement, EndpointAddress, ChannelFactory> init)
{
var binding = new CustomBinding();
binding.Elements.Add(
new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8));
var transport = url.StartsWith("https", StringComparison.InvariantCultureIgnoreCase)
? new HttpsTransportBindingElement()
: new HttpTransportBindingElement();
transport.AuthenticationScheme = System.Net.AuthenticationSchemes.Ntlm;
binding.Elements.Add(transport);
var address = new EndpointAddress(url);
var factory = new ChannelFactory<T>(binding, address);
factory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
if (init != null)
{
init(binding, transport, address, factory);
}
this._clientChannel = (IClientChannel)factory.CreateChannel();
this._channel = (T)this._clientChannel;
}
/// <summary>
/// Use this property to call service methods
/// </summary>
public T Channel
{
get { return this._channel; }
}
/// <summary>
/// Use this porperty when working with
/// Session or Cookies
/// </summary>
public IClientChannel ClientChannel
{
get { return this._clientChannel; }
}
public void Dispose()
{
this._clientChannel.Dispose();
}
}
We discovered that if the session credential was the same as the browser's process account, then just NTLM was used and the call was successful. Otherwise it would result in this captured exception:
The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'Negotiate,NTLM'.
In the end, I am fairly certain that one of the authentication schemes would pass authentication while the other wouldn't, because it was not granted appropriate access.
Try setting 'clientCredentialType' to 'Windows' instead of 'Ntlm'.
I think that this is what the server is expecting - i.e. when it says the server expects "Negotiate,NTLM", that actually means Windows Auth, where it will try to use Kerberos if available, or fall back to NTLM if not (hence the 'negotiate')
I'm basing this on somewhat reading between the lines of: Selecting a Credential Type
I know this question is old, but the solution to my application, was different to the already suggested answers. If anyone else like me still have this issue, and none of the above answers works, this might be the problem:
I used a Network Credentials object to parse a windows username+password to a third party SOAP webservice. I had set the username="domainname\username", password="password" and domain="domainname". Now this game me that strange Ntlm and not NTLM error. To solve the problems, make sure not to use the domain parameter on the NetworkCredentials object if the domain name is included in the username with the backslash. So either remove domain name from the username and parse in domain parameter, or leave out the domain parameter. This solved my issue.
Source: Stackoverflow.com