Dotnet core web api running inside docker fails to authenticate when consuming external WCF service
For anyone experiencing the same issue this is due to the way kerberos is configured on non-windows platforms. This has nothing to do with docker per say but rather running as a linux-based container.
The solution is to either switch your platform to windows or correctly configure kerberos authentication on your platform. This is discussed in more detail in the following github issues:
https://github.com/dotnet/wcf/issues/2641
and
https://github.com/dotnet/corefx/issues/9533
Calling a SOAP service in .net Core
Ok this answer is for those who are trying to connect to a WCF service from a .net Core project.
Here is the solution to my problem, using the new .net Core WCF syntax/library.
BasicHttpBinding basicHttpBinding = null;
EndpointAddress endpointAddress = null;
ChannelFactory<IAService> factory = null;
IAService serviceProxy = null;
try
{
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
endpointAddress = new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService"));
factory = new ChannelFactory<IAService>(basicHttpBinding, endpointAddress);
factory.Credentials.UserName.UserName = "usrn";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
using (var scope = new OperationContextScope((IContextChannel)serviceProxy))
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
}
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
catch (MessageSecurityException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
finally
{
// *** ENSURE CLEANUP (this code is at the WCF GitHub page *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
}
UPDATE
I got the following exception using the code above
This OperationContextScope is being disposed out of order.
Which seems to be something that is broken (or needs addressing) by the WCF team.
So I had to do the following to make it work (based on this GitHub issue)
basicHttpBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
factory = new ChannelFactory<IAService_PortType>(basicHttpBinding, new EndpointAddress(new Uri("https://someurl.com/ws/TheEndpoint.pub.ws:AService")));
factory.Credentials.UserName.UserName = "usern";
factory.Credentials.UserName.Password = "passw";
serviceProxy = factory.CreateChannel();
((ICommunicationObject)serviceProxy).Open();
var opContext = new OperationContext((IClientChannel)serviceProxy);
var prevOpContext = OperationContext.Current; // Optional if there's no way this might already be set
OperationContext.Current = opContext;
try
{
var result = await serviceProxy.getSomethingAsync("id").ConfigureAwait(false);
// cleanup
factory.Close();
((ICommunicationObject)serviceProxy).Close();
}
finally
{
// *** ENSURE CLEANUP *** \\
CloseCommunicationObjects((ICommunicationObject)serviceProxy, factory);
OperationContext.Current = prevOpContext; // Or set to null if you didn't capture the previous context
}
But your requirements will probably be different. So here are the resources you might need to help you connecting to your WCF service are here:
- WCF .net core at GitHub
- BasicHttpBinding Tests
- ClientCredentialType Tests
The tests helped me a lot but they where somewhat hard to find (I had help, thank you Zhenlan for answering my wcf github issue)
The client and server cannot communicate, because they do not possess a common algorithm - ASP.NET C# IIS TLS 1.0 / 1.1 / 1.2 - Win32Exception
There are several other posts about this now and they all point to enabling TLS 1.2. Anything less is unsafe.
You can do this in .NET 3.5 with a patch.
You can do this in .NET 4.0 and 4.5 with a single line of code
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; // .NET 4.5
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; // .NET 4.0
In .NET 4.6, it automatically uses TLS 1.2.
See here for more details:
.NET support for TLS.
Related Topics
How to Get All the Possible 3 Letter Permutations
Getting Selected Value of a Combobox
Entity Framework 4.1 Inverseproperty Attribute and Foreignkey
Local Variable and Expression Trees
Update Float Array from C++ Native Plugin
Razor Syntax Error Serializing ASP.NET Model to JSON with HTML.Raw
Change Forecolor Af a Special Word in Gridview Cell
C# Serialized JSON Date to Ruby
Add the Where Clause Dynamically in Entity Framework
Are Java and C# Regular Expressions Compatible
C# - How to Prevent Mousewheel-Scrolling in My Combobox
Dependency Injection with a Static Logger, Static Helper Class
Configure Multiple Database Entity Framework 6
Using R.Net.Community in .Net Core 2.0 Preview 1
Check a String to See If All Characters Are Hexadecimal Values
Getting Db Connection Through Singleton Class
How to Create a Progress Bar with Rounded Corners in iOS Using Xamarin.Forms