How does WCF Client retain login session - wcf

I have a WCF client connecting to a WCF Service hosted in IIS via WsHttpBinding with Message level security and UserName client credential type.
In the client, I specify my username and password in an instance of the generated proxy class representing the service. The one proxy instance is used for all subsequent calls, and the service authenticates these credentials in the custom validator either when I explicitly call Open() or when I make my first call on the service. The validation is only made on this initial call, and not on subsequent calls. e.g.:
var client = new MyServiceClient();
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password"; client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
X509CertificateValidationMode.None;
client.GetStuff1(); // authentication is made here
client.GetStuff2(); // already authenticated, no further authentication. Why/How?
client.GetStuff3(); // already authenticated, no further authentication. Why/How?
How is this session maintained? How can I configure the server and/or client so that authentication is done on each call rather than the "session" that seems to exist? Is this not determined by the <reliableSession> which I have off?
The service class is defined with these attributes:
[ServiceBehavior(IncludeExceptionDetailInFaults = true, AutomaticSessionShutdown = false, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
The client's app.config is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpBindingWithAuth" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="200000000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<!--
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" /> -->
<message clientCredentialType="UserName" negotiateServiceCredential="true"
algorithmSuite="Default"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://testmachine/MyService.svc"
binding="wsHttpBinding" bindingConfiguration="wsHttpBindingWithAuth"
contract="NewServiceIIS.IMyService" name="wsHttpBindingWithAuth">
<identity>
<certificate encodedValue="ZZZZ" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

This was the source of my frustration and now it is a bliss for you (i.e. you dont need to supply user/pass again)!
Yes, authentication is stored in the channel. Once channel opened, the ClientCredentials cannot be changed. Channel establishes a security context which is retained within the Channel. With wsHttpBinding and message security, this is username/password which is sent to the server everytime.
This is by design. The only way to re-authenticate is to close the channel/proxy and create a new proxy.
If you wonder what establishing security context is, have a look at What are the impacts of setting establishSecurityContext="False" if i use https?

Related

UPN Identity for SOAP call getting switched in a clustered service

I make a call in which the WCF service client is constructed like so:
var endpointIdentity = EndpointIdentity.CreateUpnIdentity("DOMAINNAME\serviceAccountName#DOMAINNAME");
var endpointAddress = new EndpointAddress(theServiceUri, endpointIdentity);
var serviceClient = new ServiceReference.ServiceClient("WSHttpBinding_Service", endpointAddress);
The binding looks like this:
<wsHttpBinding>
<binding name="WSHttpBinding_Service"
closeTimeout="02:00:00"
openTimeout="02:00:00"
receiveTimeout="02:00:00"
sendTimeout="02:00:00"
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
messageEncoding="Text"
textEncoding="utf-8"
useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<reliableSession ordered="true"
inactivityTimeout="02:00:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
This code is running in a clustered service. When serviceClient calls one of its methods, I'm getting this error:
SOAP security negotiation with 'http://host-name:PORT/EndpointName' for target 'http://host-name:PORT/EndpointName' failed. See inner exception for more details. ---> System.ComponentModel.Win32Exception: Security Support Provider Interface (SSPI) authentication failed. The server may not be running in an account with identity 'host/host-name'. If the server is running in a service account (Network Service for example), specify the account's ServicePrincipalName as the identity in the EndpointAddress for the server. If the server is running in a user account, specify the account's UserPrincipalName as the identity in the EndpointAddress for the server.
Please note: the identity being used for the SOAP call is the host name (emphasized above), not DOMAINNAME\serviceAccount like it should, and like it does when I run through the debugger. What settings might be off on the server to cause this?
I checked the wsdl the service is publishing, and the wsdl:service block looks how I would expect:
<wsdl:service name="Service">
<wsdl:port name="WSHttpBinding_Service" binding="tns:WSHttpBinding_Service">
<soap12:address location="http://localhost:PORT/EndpointName"/>
<wsa10:EndpointReference>
<wsa10:Address>http://localhost:PORT/EndpointName</wsa10:Address>
<Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<Upn>serviceAccount#DOMAINNAME</Upn>
</Identity>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>

How do I consume a WS-Security service in WCF over HTTPS?

I'm trying to consume a WS-Security enabled service with WCF. Authentication works using a UsernameToken. I'm not very knowledgeable with WCF web service clients, but I think my configuration below works for regular HTTP communication. I (mostly) used this guide to configure it. The main difference is that I used the VS2010 "Add Service Reference" UI instead of a command prompt.
My problem is that I need to do this over HTTPS. When I use <security mode="Message"> in my app.config, I believe my soap envelope contains the needed WS-Security headers. I can't tell for sure because I can't get logging to work. However, I get the following error: The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via.
Below are the contents of my app.config file, as well as a sample of my client code.
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="Omitted" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://omitted.com/service" binding="wsHttpBinding" bindingConfiguration="Omitted" contract="Omitted.Omitted" name="Omitted" />
</client>
</system.serviceModel>
var service = new OmittedClient();
service.ClientCredentials.UserName.UserName = "username";
service.ClientCredentials.UserName.Password = "password";
var response = service.DoSomething(new DoSomethingRequest());
Thanks to 500 - Internal Server error for helping me figure it out. Here are the steps I took:
Generate a proxy using Visual Studio/WCF.
Change the security mode to TransportWithmessageCredential.
Use the following code to specify a username/password.
var client = new WebServiceClient();
client.ClientCredentials.UserName.UserName = "USERNAME";
client.ClientCredentials.UserName.Password = "PASSWORD";
If you get a response back, but WCF complains when processing it, there might be a timestamp missing from the response. If that's the case, try this to fix it.
// WCF complains about a missing timestamp (http://www.west-wind.com/weblog/posts/2007/Dec/09/Tracing-WCF-Messages)
var elements = service.Endpoint.Binding.CreateBindingElements();
elements.Find().IncludeTimestamp = false;
service.Endpoint.Binding = new CustomBinding(elements);

WCF- Duplex connection (hosted in IIS)

I have a full duplex, I run successfully in my local machine.
I host it in my server (IIS - server 2008 R2-STANDARD), and trying to connect, as following:
this.myCallbackProxy = new MyCallbackProxy();
InstanceContext cntx = new InstanceContext(myCallbackProxy);
this.Proxy = new MyServiceClientProxy(cntx, "WSDualHttpBinding_I_BridgeWCFService");
this.Proxy.ClientCredentials.Windows.ClientCredential.UserName = "YY";
this.Proxy.ClientCredentials.Windows.ClientCredential.Password = "PP";
Now, when I try to call an API, I stuck until time out.
I tried to configure the WCF in the IIS to connect as specific user , but then when I try to call an API from my client, I get the following exception:
"The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response"
I must mention that I have another WCF hosted in same IIS, with same user (server user name), and it works perfect. (I create another (similar) application poll for the duplex WCF)
My config file:
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_I_BridgeWCFService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483646" maxReceivedMessageSize="2147483646"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483646"
maxArrayLength="2147483646" maxBytesPerRead="2147483646" maxNameTableCharCount="2147483646" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"/>
<security mode="None">
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://xx.xx.xx.xx/_Bridge/_BridgeWcfService.svc"
binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_I_BridgeWCFService"
contract="_BridgeWcfServiceReference.I_BridgeWCFService"
name="WSDualHttpBinding_I_BridgeWCFService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</client>

The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="pc"'

Server:
<system.serviceModel>
<services>
<service name="Service" behaviorConfiguration="md">
<!-- Service Endpoints -->
<endpoint address="SslService" binding="basicHttpBinding" bindingConfiguration="security" contract="IService"/>
<host>
<baseAddresses>
<add baseAddress="https://pc:8080/Service.svc"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="security">
<security mode="Transport">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="md">
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="ClassLibrary1.CustomUserNameValidator, ClassLibrary1" />
</serviceCredentials>
<serviceMetadata httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
ClassLibrary1.CustomUserNameValidato:
public class CustomUserNameValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName != "111" || password != "111")
{
throw new System.ServiceModel.FaultException("Unknown username or incorrect password");
}
}
}
Client:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" 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="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="">
<extendedProtectionPolicy policyEnforcement="Never" />
</transport>
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://pc:8080/Service.svc/SslService" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
name="BasicHttpBinding_IService" />
</client>
</system.serviceModel>
ServiceReference1.ServiceClient s = new WindowsFormsApplication1.ServiceReference1.ServiceClient();
s.ClientCredentials.UserName.UserName = "111";
s.ClientCredentials.UserName.UserName = "111";
MessageBox.Show(s.GetData(3)); // <---- ERROR
The HTTP request is unauthorized with client authentication scheme 'Basic'. The authentication header received from the server was 'Basic realm="pc"'.
I had created a client like this:
using (var client = new Client())
{
client.ClientCredentials.UserName.UserName = <username>;
client.ClientCredentials.UserName.Password = **<WRONG_PASSWORD>**;
...
}
The security section of my binding looked like this:
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="Basic" realm="" />
</security>
And I saw this error come back. Once I corrected the password, everything worked.
I'm assuming you are hosting your servicehost on the IIS. Then the problem is that the IIS intercepts the https request and performs IIS-level authentication before the WCF framework and your custom validator has a chance to kick in.
In your example, the IIS will actually look for a local user '111' with password '111' on the server running the IIS. Try creating this user on the server, and you will probably get a different result.
One solution is to host your WCF servicehost somewhere else, for example in a Windows Service. Another solution is to change your security scheme to TransportWithMessageCredential. Finally, you could check this OSS http module out: Custom Basic Authentication for IIS - seems to do the trick we need.
Try to send username and password not in http with basic authentication (this can embarrass IIS), but only in soap-message headers with following scheme:
<binding name="...">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName" />
</security>
</binding>
How to: Use Transport Security and Message Credentials
Maybe you also need to additionally specify <transport clientCredentialType="None">
I posted an answer here: Can not call web service with basic authentication using WCF
transport clientcredentialType is TransportCredentialOnly
Looks like you set the user name twice instead of the user name and password.
When you have basic authentication and you do not send the username and password with the request you get a challenge response back.
I applied all the things which are above mentioned but my problem is not solved.
In my case this is happening because of proxy server. Then I removed all the proxy and run my web service. Then it is working fine.
Hope this will you!!!!!!

WCFTestClient The HTTP request is unauthorized with client authentication scheme 'Anonymous'

I've created one WCF service and deployed it on Server. When I browse this service it gives me positive response with ?wsdl URL. Now I'm trying to test the service through WCF Test client. It shows proper metadata. But when I try to invoke any of the method from the service it shows me an exception... here are the erro details with stack trace..
The HTTP request is unauthorized with
client authentication scheme
'Anonymous'. The authentication header
received from the server was
'Negotiate,NTLM'.
Server stack trace:
at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest
request, HttpWebResponse response,
WebException responseException,
HttpChannelFactory factory)
The HTTP request is unauthorized with client
authentication scheme 'Anonymous'. The
authentication header received from
the server was 'Negotiate,NTLM'.
Server stack trace:
at
System.ServiceModel.Channels.HttpChannelUtilities.ValidateAuthentication(HttpWebRequest
request, HttpWebResponse response,
WebException responseException,
HttpChannelFactory factory)
Client Bindings:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IServiceMagicService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
Server Bindings:
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_SEOService" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true" />
</security>
</binding>
<binding name="WSHttpServiceMagicBinding" closeTimeout="00:10:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="true" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="999524288" maxReceivedMessageSize="655360000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="900000" maxArrayLength="900000" maxBytesPerRead="900000" maxNameTableCharCount="900000"/>
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
<security mode="None">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Client's Client Section:
<client>
<endpoint address="http://hydwebd02.solutions.com/GeoService.Saveology.com/ServiceMagicService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IServiceMagicService"
contract="IServiceMagicService" name="WSHttpBinding_IServiceMagicService" />
</client>
Server's Services Section:
<services>
<service behaviorConfiguration="GeoService.Saveology.com.CityStateServiceProviderBehavior"
name="GeoService.Saveology.com.CityStateServiceProvider">
<endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_SEOService"
contract="SEO.Common.ServiceContract.ICityStateService" />
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
</service>
<service behaviorConfiguration="GeoService.Saveology.com.ServiceMagicServiceProviderBehavior"
name="GeoService.Saveology.com.ServiceMagicServiceProvider">
<endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpServiceMagicBinding"
contract="SEO.Common.ServiceContract.IServiceMagicService">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
</services>
I didn't have control over the security configuration for the service I was calling into, but got the same error. I was able to fix my client as follows.
In the config, set up the security mode:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
In the code, set the proxy class to allow impersonation (I added a reference to a service called customer):
Customer_PortClient proxy = new Customer_PortClient();
proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
I have a similar issue, have you tried:
proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
Another possible solution to this error that I found. Might not have answered OP's exact question but may help others who stumble across this error message.
I was creating my Client in code using WebHttpBinding, in order to replicate the following line:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="Windows" />
</security>
I had to do:
var binding = new WebHttpBinding(WebHttpSecurityMode.TransportCredentialOnly);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Windows;
as well as setting proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
I had a similar problem and tried everything suggested above. Then I tried changing the clientCreditialType to Basic and everything worked fine.
<basicHttpBinding>
<binding name="BINDINGNAMEGOESHERE" >
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"></transport>
</security>
</binding>
</basicHttpBinding>
I see this isn't answered yet, this is an exact quote from here:
WSHttpBinding will try and perform an internal negotiate at the SSP layer. In order for this to be successful, you will need to allow anonymous in IIS for the VDir. WCF will then by default perfrom an SPNEGO for window credentials. Allowing anonymous at IIS layer is not allowing anyone in, it is deferring to the WCF stack.
I found this via: http://fczaja.blogspot.com/2009/10/http-request-is-unauthorized-with.html
After googling: http://www.google.tt/#hl=en&source=hp&q=+The+HTTP+request+is+unauthorized+with+client+authentication+scheme+%27Anonymous
Here's what I had to do to get this working. This means:
Custom UserNamePasswordValidator (no need for a Windows account, SQLServer or ActiveDirectory -- your UserNamePasswordValidator could have username & password hardcoded, or read it from a text file, MySQL or whatever).
https
IIS7
.net 4.0
My site is managed through DotNetPanel. It has 3 security options for virtual directories:
Allow Anonymous Access
Enable Basic Authentication
Enable Integrated Windows Authentication
Only "Allow Anonymous Access" is needed (although, that, by itself wasn't enough).
Setting
proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
Didn't make a difference in my case.
However, using this binding worked:
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Windows" />
<message clientCredentialType="UserName" />
</security>
I had the same error today, after deploying our service calling an external service to the staging environment in azure. Local the service called the external service without errors, but after deployment it didn't.
In the end it turned out to be that the external service has a IP validation. The new environment in Azure has another IP and it was rejected.
So if you ever get this error calling external services
It might be an IP restriction.
I had this error too , and finally this codes worked for me in dot net core 3.1
first install svcutil in command prompt : dotnet tool install --global dotnet-svcutil
Then close command prompt and open it again.
Then create the Reference.cs in command prompt :
dotnet-svcutil http://YourService.com/SayHello.svc
(It needs an enter key and UserName and Password)
Add a folder named Connected Services to project root.
Copy Reference.cs file to Connected Services folder.
Add these 4 lines to Reference.cs after lines where creating BasicHttpBinding and setting MaxBufferSize :
result.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
result.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
result.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
Use this service in your Controller :
public async Task<string> Get()
{
try
{
var client = new EstelamClient();
client.ClientCredentials.UserName.UserName = "YourUserName";
client.ClientCredentials.UserName.Password = "YourPassword";
var res = await client.EmployeeCheckAsync("service parameters");
return res.ToString();
}
catch (Exception ex)
{
return ex.Message + " ************ stack : " + ex.StackTrace;
}
}
Do not forget install these packages in csproj :
<PackageReference Include="System.ServiceModel.Duplex" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.Http" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.6.*" />
<PackageReference Include="System.ServiceModel.Security" Version="4.6.*" />
Just got this problem on a development machine (production works just fine). I modify my config in IIS to allow anonymous access and put my name and password as credential.
Not the best way I am sure but it works for testing purposes.
Try providing username and password in your client like below
client.ClientCredentials.UserName.UserName = #"Domain\username";
client.ClientCredentials.UserName.Password = "password";