I have a WCF service I have created in a WebApplication with the following configuration in web.config
<service name="RedwebServerManager.WebApplication.DesktopService"
behaviorConfiguration="ServBehave">
<endpoint
address=""
binding="basicHttpBinding"
bindingConfiguration="basicBind"
contract="RedwebServerManager.WebApplication.IDesktopService"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="basicBind">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
This service needs to take in WindowsCredentials in to get information in a database based upon the authenticated user. This service current has one method implementing an interface with the following signature
[ServiceContract]
public interface IDesktopService
{
/// <summary>
/// Gets the clients.
/// </summary>
/// <returns>IEnumerable<ClientServiceModel>.</returns>
[OperationContract]
IEnumerable<ClientServiceModel> GetClients();
}
I have a Windows Forms application which is consuming the WCF service and I want to pass through the credentials of the current user using the application as this will all be sitting on our domain. The app.config is as follows
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDesktopService">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Windows" proxyCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://redwebservermanager.redweb.network/DesktopService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDesktopService"
contract="ManagerService.IDesktopService" name="BasicHttpBinding_IDesktopService" />
</client>
</system.serviceModel>
If I manually set the credentials username and password everything works correctly however I have been trying
managerService.ClientCredentials.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials
so that I can pass the current users credentials over but I keep getting an error on the call to GetClients() that the username and password is not set.
Can anyone help me? I also tried adding
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
to the method but this made no difference.
You can get the Username (and more information other than the password) using one of the following ways:
//1.
System.Security.Principal.WindowsIdentity.GetCurrent();
//2.
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
WindowsPrincipal user = (WindowsPrincipal)System.Threading.Thread.CurrentPrincipal;
//3.
WindowsIdentity ident = WindowsIdentity.GetCurrent();
WindowsPrincipal user = new WindowsPrincipal(ident);
But, there is no way you can access the password of the user. Please refer to this question
Once you receive the Identity information, you can pass the username to WCF using OutgoingMessageHeaders, like:
MessageHeader<string> header = new MessageHeader<string>(userName);
OperationContextScope contextScope = new OperationContextScope(InnerChannel);
OperationContext.Current.OutgoingMessageHeaders.Add(
header.GetUntypedHeader("String", "System"));
And in the WCF service implementation you can read it like:
OperationContext context = OperationContext.Current;
if (context != null)
{
try
{
_LoginName = OperationContext.Current.IncomingMessageHeaders.GetHeader<string>("String", "System");
}
catch
{
_LoginName = string.Empty;
}
}
Please let me know if this helps or if you have any other questions.
Thank you, Soma.
I feel like you can find your answer here: Intranet - web to remote wcf CredentialCache.DefaultNetworkCredentials not working. Basically you can't use Windows Authentication from Windows Forms application to WCF. You can only use it directly with WCF or Forms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With