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

I am trying to program a VisualWebPart using Visual Studio 2010 which has to do a simple thing: invoke a web service (hosted in a remote server, NOT locally). When I execute within the Sharepoint site (version 2010, which I have published in my IIS) I get this error:
"The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM'."
Pardon my ignorance, but the only difference here is the case of the Ntlm authentication scheme! I have been all over the web and found many related problems, but none of the solutions worked. Almost ALL solutions i found involve modifications in the webservice security configuration, this is not an option for me.
Looking for a solution, I created a sample windows form and invoked the web service from it: no problems whatsoever.
In order to be able to invoke the webservice correctly this is the necessary security configuration:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="Ntlm" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
I believe the problem is that I haven´t been able to properly set this security property to the web.config of my Sharepoint site, since I tried to put it in the security tag that appears in the web.config but still get the same error.
Any further information needed please ask, I am REALLY desperate, for days I have been with the SAME error.

In the end I was given permissions in their server: more precisely in the database which was the one that wouldn't let me create the web part in the server. Once this was done, the call to the webservice worked just fine, because they have the web.config correctly configured.

Related

Client App with WsHttpBinding gets "no endpoint listening at..."

I have a client application which talks to our Web Service hosted on a server (we'll call it hostServer). My client application can build and connect fine using basicHttpBinding. However, I'm trying to impliment wsHttpBinding for security reasons.
Last week before lunch I could swear it was working with a hardcoded certificate. Came back from lunch, checked in my code and now it won't run. I keep getting "There was no endpoint listening at https://hostServer:1234/Service.svc/MyServiceName that could accept the message. This is often caused by an incorrect address or SOAP action.". I've tried re-checking my settings, retracing my steps, but can't seem to get back to the functioning state I was in.
I am using a ServiceReference with an address of "https ://hostServer:1234/Service.svc?singleWsdl". I can navigate to "https ://hostServer:1234/Service.svc" without a problem and view the Wsdl.
My client code is
WSHttpBinding wsBinding = new WSHttpBinding(SecurityMode.Transport);
wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
Client = new MyServiceName(wsBinding, new EndpointAddress(endpoint));
Client.ClientCredentials.ClientCertificate.SetCertificate(
StoreLocation.CurrentUser,
StoreName.My,
X509FindType.FindBySubjectName,
"localCertName");
Client.ChangePassword("test_user", "pt", "a1");
My value endpoint = https://hostServer:1234/Service.svc/MyServiceName
My IIS site is set up with Binding for Http and Https (with correct IP & Port ID)
I really need to get this code working before taking off (my wife is due with our second child any day). I've been working to debug this now for 2 days, in addition to the time it took me to stand it up as is. Please help.
So I was finally able to get this working again. Listing what steps were performed below in hopes that it might help someone else.
On IIS Server (IIS Manager):
Modified "Site Bindings" to include HTTP & HTTPS (w/different Port Numbers)
Set SSL setting to "Require SSL" and "Accept"
On IIS Server (Web.Config):
Added
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security mode="Transport">
<transport clientCredentialType ="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
to the "System.ServiceModel" tag.
Also, added 'bindingConfiguration="wsHttpEndpointBinding"' to my endpoint.
In Code
Updated Endpoint address to use that generated on the IIS Server.
Used the following code for creating the endpoint
WSHttpBinding wsBinding = new WSHttpBinding(SecurityMode.Transport);
wsBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
Client = new ServiceClient(wsBinding, new EndpointAddress(endpoint));
Client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMac‌​hine, StoreName.My, X509FindType.FindByIssuerName, certName);

Does the Navision (2009) Webservice support authentication to a remote database?

I'm currently attempting to deploy the Navision webservice (from Dynamics Navision 2009) and am finding that the webservice authenticates when connecting to a local Navision SQL database but NOT a remote Navision SQL database.
So we have servers S (with a full Navision install) and W (with only the Services installed). The CustomSettings.config file on these two systems is identical except that where S references localhost:
<add key="DatabaseServer" value="127.0.0.1"></add>
<add key="ClientCredentialType" value="Windows"></add>
W references S:
<add key="DatabaseServer" value="S"></add>
<add key="ClientCredentialType" value="Windows"></add>
(Other details omitted.) The webservice itself is running as the same domain user in both cases, and that user is authenticated within Navision.
When I connect to the webservice which is running on S, authentication works and the service proceeds as normal:
http://S:7047/DynamicsNAV/WS/Company/Codeunit/RLIntegartion
I'll omit the actual result here. When connecting via W instead:
http://W:7047/DynamicsNAV/WS/Company/Codeunit/RLIntegartion
the webservice instead returns XML indicating an authentication failure:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">
a:Microsoft.Dynamics.Nav.Types.NavDatabasePasswordException
</faultcode>
<faultstring xml:lang="en-US">
The login failed when connecting to SQL Server S.
</faultstring>
<detail>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
The login failed when connecting to SQL Server S.
</string>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
I can configure an ODBC connection on W to the Navision database on S and the connection succeeds and authenticates correctly, so the actual database connection and authentication appears to be fine.
I'm aware that the webservice itself must normally be accessed locally so that any files written can be read from where the Navision webservice has written them, but from what I can tell in the documentation the webservice may legitimately access the database from a separate server. However, in practice (per above) this doesn't seem to actually work.
Is this a restriction that Navision imposes? If not, does anyone have any suggestions as to why the webservice is failing to authenticate when accessing a remote database when the same webservice succeeds locally?
Or could it be a limitation imposed by the codeunit programmers? I've spoken to them and they indicate that this should work, but clearly it does not.
That is known problem of Nav 2009. In later versions it's working without additional tricks. To solve this you need to create SPN.
Me personally was not able to set it properly so I just always installed web service tier on the same server with SQL. In this case it works.
There are three participants in this scheme - DB, web service and the client (that connects to this service). The problem appears only when all these three participants are on three different machines.
This three-machine setup will work only if the following requirements are fulfilled:
1) your client is capable of using Kerberos authentication (e.g. Internet Explorer or .NET applications are capable, but Chrome or PHP applications are not)
2) you set up NAV to use Kerberos authentication (as opposed to NTLM) and you set up delegation.
Delegation is a process that allows NAV server (or web service) to take the authentication ticket that came from client and pass it to SQL Server. You need to explicitly allow this in Active Directory setup. For that you will need SPNs - they basically describe the subjects that take part in this delegation.
You may refer to these manuals to setup the whole thing:
MSDN Walkthrough: Installing the Three Tiers on Three Computers
MSDN How to: Configure Web Services with Delegation
NAV 2009 Web Services on a three machine setup
You can also revert to more simple setup of using two-machines setup. In this case, either NAV server and SQL server should be on the same machine, or NAV server and the web service client should be on the same machine. As an example of the latter, you may create a small custom web service which acts as a proxy for your calls, and publish it on the same machine as NAV server/web service.

Azure website connection to Azure Service

I have a asp.net MVC website which communicates to a SQL database through a web service. When set up in IIS it all works fine. I recently migrated the whole solution to Azure by publishing the Website and webservice as Web Apps. Under IIS the web.config of the website connects to the service endpoint using:
<client>
<endpoint address="http://localhost:7070/Services.svc"binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITrain" contract="ServiceReference1.ITrain" name="BasicHttpBinding_ITrain"/>
</client>
In Azure i have changed this to:
<client>
<endpoint address="http://<sitename>.azurewebsites.net/Services.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITrain" contract="ServiceReference1.ITrain" name="BasicHttpBinding_ITrain" />
</client>
The two web apps do not communicate.
Should i be doing something differently or does the problem lie somewhere else?
If you say the WSDL looked okay, the next thing I would recommend would be building a new simple Console app to try to talk to it. Use Add Service Reference in the Solution Explorer and provide the http://.azurewebsites.net/Services.svc URL. If Add Service Reference has a problem, you have some kind of WSDL error. But if it succeeds, your project will have auto-generated code to talk to that service. The example at https://msdn.microsoft.com/en-us/library/bb386386.aspx walks through this.
If the Console app succeeds in talking to the service, look very carefully at the generated app.config to see if it differs from your existing config files.
Ron Cain MSFT

IIS 7.5 Handling 500 Errors Differently Than IIS 6.0

Our Classic ASP application contains a web service that can be called over an HTTP. POST or GET. The web service does its duty and then writes out, using Response.Write, an XML message over HTTP.
Here is an example.
Response.ContentType = "text/xml"
Response.Status = "500 Error"
Response.Write("<?xml version=""1.0"" ?>")
Response.Write("<PeelMe>")
Response.Write("<Error>Your orange was actually blue!</Error>")
Response.Write("</PeelMe>")
When the application was hosted in IIS 6.0, the caller received the XML and was able to parse it just fine.
Then, we switched to IIS 7.5.
As in IIS 6.0, we set up a customer error page, let's call it "Blah.asp", to render certain custom text to the browser when an error occurred while an actual user was browsing the site. When we switched to IIS 7.5, all 500 error messages written out to the web service caller were now captured by IIS 7.5, redirecting the thread to Blah.asp and subsequently writing the HTML of Blah.asp back to the caller.
Here is my question:
How do I get IIS 7.5 to act like IIS 6.0 so that when I want to write out a 500 Error message back to a web service caller, I can do that, without IIS 7.5's custom error handling getting in the way?
Since IIS7 the web.config offers more options. You could try the following to get the bevaviour you are after:
<system.webServer>
<httpErrors errorMode="Detailed">
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" prefixLanguageFilePath="" path="/[CUSTOMERRORPAGE].asp" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
Did you try setting the app pool to asp classic? We've been doing a lot of upgrades lately; constantly running into issues with 7.5.
Setting the app pool back, resolves probably 80% of our issues.

Sharepoint denying access to asmx methods

We have a site running on MOSS 2007 which makes calls to custom web service asmx methods on the same domain from the client.
On the live site requests are getting redirected to the following url:
http://[domain]/_layouts/error.aspx?ErrorText=Request format is unrecognized for URL unexpectedly ending in %27%2FIsSuspectWaterLevel%27.
We've added the following to the sites web.config without any joy:
<system.web>
<webServices>
<protocols>
<add name="HttpSoap" />
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
</webServices>
...
</system.web>
Interestingly enough we don't have this issue on the test server which is supposed to be pretty identical to the live server.
Any ideas to what other variable might be at play here?
Thanks in advance for any ideas,
Gavin
Update:
While a call to
http://[Domain]/_vti_bin/Custom/CustomFunctionality.asmx/IsSuspectWaterLevel
fails, I can still access
http://[Domain]/_vti_bin/Custom/CustomFunctionality.asmx?op=IsSuspectWaterLevel
though it fails when I invoke the method in the same way.
I wonder if this helps shed more light on the issue?
Another Update:
I've just observed the same error on the dev server. Removing the apps dll from GAC and then re-copying it in solved the issue. The live server tested fine with initial deployment so perhaps there's an issue with Sharepoint loosing some reference over time? Clutching at straws as very confusing behaviour!
Yet Another Update:
It seems everytime I touch (open and save) the web.config file in 12 Hives the problem is fixed again for a period, but after a while the problem comes back. I wonder if it's anything to do with the app pool being recycled?
C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\ISAPI\web.config
An inelegant workaround to this issue that works for us: We've swapped out the web service asmx end point for a web handler ashx endpoint. This doesn't suffer the same issue for some reason.
I'm guessing from this that there's some issue creeping in after a period of time which is causing urls to resolve incorrectly. I suspect that the / after the .asmx in the url is the curprit. The ashx endpoint implemented is working purely on url parameters and posted data.
Obviously this work around won't always be an option for others who might experience the same issue as we're loosing a lot of the rich web service functionality that's pre-baked in to an asmx endpoint.
Unfortunately I won't be able to test any other solutions that people might put forward from now on as we've moved away from the web service asmx approach. Sorry.