I’m developping an « auto-connect » mode between a WPF application and a Windows service throw WCF. I want to allow only trusted domain users to connect to a particular WCF service, without the need of windows credentials (the user is already logged on his windows session). This service will next log the user to the application.
I’ve created a WCF service with Security mode to « Transport » and Transport.ClientCredentialType to « Windows » (same binding on both client & server). There are other WCF services running in the same application, with security mode set to « None ».
When I run the windows service on a domain machine under LocalService account, and run the client on another machine under a domain user account, I can get the user Windows Identity « DOMAIN\user » on the server side in the OperationContext object. I see that Kerberos is used, and I think there is some kind of impersonation, wich is ok.
But when I run the windows service on a Workgroup machine (out of domain), where no domain user is known, the OperationContext WindowsIdentity is set to « MACHINE_NAME\Administrator » (the local session created on the server). There is no error, no exception on the service call, and I can’t figure out why. The IsAuthenticated property on WindowsIdentity object is always set to true.
I’ve already tested with security mode to « Message ».
I wanted to know if there is a possibility to tell WCF to reject ALL connections that are not truly authentified ?
UPDATE: here some informations that might help:
- Client app is a WPF application
- Server is a classic Windows service, running under LOCAL SERVICE
- Bindings are net.tcp
- Client proxy classes are generated via svcutil.exe
- Everything is done by code, no config file
- Here is the code creating a ServiceClient:
public static TClient Create<TClient, TChannel>(params IContractBehavior[] behaviors)
where TChannel : class
where TClient : ClientBase<TChannel>
{
var typeOfClient = typeof(TClient);
var ctor = typeOfClient.GetConstructor(new[] { _bindingType, _endpointAddressType });
if (ctor == null)
{
throw new Exception($"{typeOfClient} has no constructor taking 2 parameters ({_bindingType},{_endpointAddressType})");
}
var address = getClientBaseEndPointAddress(typeof(TChannel));
var binding = getBinding<TClient>(address.Uri.Scheme);
var clt = (TClient)ctor.Invoke(new object[] { binding, address });
foreach (var behavior in behaviors)
{
clt.ChannelFactory.Endpoint.Contract.Behaviors.Add(behavior);
}
manageDataContractResolver<TClient, TChannel>(clt);
clt.setOperationTimeout(binding.SendTimeout);
return clt;
}
- getBinding method is shared by Client & Server app:
var ret = new NetTcpBinding
{
MaxBufferSize = bc.MessageSize,
MaxBufferPoolSize = bc.MessageSize,
...
};
// Secured or not
if (secured)
{
ret.Name = "Default_Secured_Binding";
ret.Security.Mode = SecurityMode.Transport;
ret.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
}
else
{
ret.Security.Mode = SecurityMode.None;
ret.Name = "Default_Binding";
}
- According to this: Understanding WCF Windows Authentication or this The server has rejected the client credentials, WCF as Windows Service
I thought WCF would reject any request that are not fully authenticated, but I can't get any "authentication error".
Let me know if you need more information.