I'm attempting to consume a SOAP Webservice using a WCF Web Service Reference.
I have been able to successfully consume the SOAP web service in a .NET 4.8 framework project using the System.Web.Servicees Web Service Reference. However I need to consume the web service in a .NET Core project. The WCF generated class from the WSDL is different than the .NET framework web service. It seems like you now have to use the generated WebServiceClient to interact with the web service.
I believe the web service requires basic authentication as I was able to authenticate using basic authentication in the .NET framework project.
Here is the error message I'm getting when I try to execute one of the web service's methods.
System.ServiceModel.Security.MessageSecurityException
HResult=0x80131500
Message=The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was ''.
Source=System.Private.ServiceModel
Here is my code which instantiates the client and calls the method
var callContext = new CAdxCallContext();
callContext.codeLang = "ENG";
callContext.poolAlias = "BGRTEST";
callContext.requestConfig = "adxwss.trace.on=on&adxwss.trace.size=16384&adonix.trace.on=on&adonix.trace.level=3&adonix.trace.size=8";
var proxy = new CAdxWebServiceXmlCCClient();
proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "password";
string _InputXml = "<PARAM>"
"<GRP ID= \"GRP1\">"
"<FLD NAME = \"ITMREF\">" 100001 "</FLD>"
"</GRP>"
"</PARAM>";
try
{
var response = proxy.run(callContext, "BGR_SIEPRO", _InputXml);
}
finally
{
proxy.Close();
}
My WCF service connection: WCF Connected Service Screenshot
The Auto-generated WCF WebServiceClient: https://github.com/abiddle-bgr/Test/blob/main/CAdxWebServiceXmlCCClient.cs
CodePudding user response:
Did you set secure transfer mode? similar to this: Basic Authentication in WCF client.
<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
proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
You can look at this post.
CodePudding user response:
I ended up having to manually inject the headers by creating a custom endpoint and adding it to the proxy as a custom endpoint behavior.
var proxy = new CAdxWebServiceXmlCCClient();
proxy.Endpoint.EndpointBehaviors.Add(new CustomEndpoint());
public class ClientMessageInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
// Nothing Here
Console.Write(reply.ToString());
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic "
Convert.ToBase64String(Encoding.ASCII.GetBytes("USERNAME" ":"
"PASSWORD"));
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestProperty);
return null;
}
}
public class CustomEndpoint : IEndpointBehavior
{
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
// Nothing here
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new ClientMessageInspector());
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
// Nothing here
}
public void Validate(ServiceEndpoint endpoint)
{
// Nothing here
}
}