all Technical posts

Impersonate WCF Credentials when calling a WCF Service

One of the requirements that I regularly encounter is that I need to call WCF TCP or WCF Web with trusted authentication.
My development laptop or my virtual machines are never member of the customer domain so that makes it almost impossible to develop and test against services of the customer. For Example, Microsoft Dynamics is often used with WCF-TCP which only allows for trusted authentication.

I did some searching on the internet and there doesn’t seem to be a good solution for it. Or at least I was not able to find it. That is why I created a Behavior to do just that. I also added an option “Enabled” to the behavior, if that is set to “False” the behavior will not impersonate.

I did this to make the behavior “Deployment Framework Friendly”. I used the deployment framework and have impersonation working on my local machine. On the servers in the DTAP environment the credentials of the “BizTalk Service Account” were used and Impersonation was set to “False”. By introducing this variable you can use the same binding file for every environment and configure the actual impersonation in the “EnvironmentSettings” spreadsheet which is part of the BTDF.

But this post is about a “problem” and should include a solution as well. So here is the complete working code of this behavior.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Configuration;
using System.Configuration;
namespace Axon.Biztalk.WCF.Extensions
{
public class ImpersonateNtlmCredentialsBehaviourElement : BehaviorExtensionElement
{
[ConfigurationProperty(&quot;Username&quot;, DefaultValue = &quot;<enter username>&quot;)]
public string Username
{
get { return (string)base[&quot;Username&quot;]; }
set { base[&quot;Username&quot;] = value; }
}
[ConfigurationProperty(&quot;Password&quot;, DefaultValue = &quot;<enter password>&quot;)]
public string Password
{
get { return (string)base[&quot;Password&quot;]; }
set { base[&quot;Password&quot;] = value; }
}
[ConfigurationProperty(&quot;Active&quot;, DefaultValue = false)]
public bool Active
{
get { return (bool)base[&quot;Active&quot;]; }
set { base[&quot;Active&quot;] = value; }
}
[ConfigurationProperty(&quot;Domain&quot;, DefaultValue = &quot;<enter Domain>&quot;)]
public string Domain
{
get { return (string)base[&quot;Domain&quot;]; }
set { base[&quot;Domain&quot;] = value; }
}
protected override object CreateBehavior()
{
return new ImpersonateNtlmCredentialsBehaviour(this);
}
public override Type BehaviorType
{
get { return typeof(ImpersonateNtlmCredentialsBehaviour); }
}
}
}

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
namespace Axon.Biztalk.WCF.Extensions
{
public class ImpersonateNtlmCredentialsBehaviour : IEndpointBehavior
{
private ImpersonateNtlmCredentialsBehaviourElement config = null;
public ImpersonateNtlmCredentialsBehaviour(ImpersonateNtlmCredentialsBehaviourElement config)
{
this.config = config;
}
#region IEndpointBehavior Members
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
if (bindingParameters == null)
{
throw new ArgumentNullException(&quot; bindingParameters & quot;);
}
if (config.Active == true)
{
SecurityCredentialsManager manager = bindingParameters.Find<ClientCredentials>();
if (manager != null)
{
var cc = endpoint.Behaviors.Find<ClientCredentials>();
cc.UserName.Password = config.Password;
cc.UserName.UserName = config.Domain + @&quot;\&quot; +config.Username;
cc.Windows.ClientCredential.UserName = config.Username;
cc.Windows.ClientCredential.Password = config.Password;
cc.Windows.ClientCredential.Domain = config.Domain;
}
else
{
var cc = endpoint.Behaviors.Find<ClientCredentials>();
cc.UserName.Password = config.Password;
cc.UserName.UserName = config.Domain + @&quot;\&quot; +config.Username;
cc.Windows.ClientCredential.UserName = config.Username;
cc.Windows.ClientCredential.Password = config.Password;
cc.Windows.ClientCredential.Domain = config.Domain;
bindingParameters.Add(this);
}
}
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
{ }
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
{ }
public void Validate(ServiceEndpoint endpoint)
{ }
#endregion
}
}

Subscribe to our RSS feed

Hi there,
how can we help?

Got a project in mind?

Connect with us

Let's talk

Let's talk

Thanks, we'll be in touch soon!

Call us

Thanks, we've sent the link to your inbox

Invalid email address

Submit

Your download should start shortly!

Stay in Touch - Subscribe to Our Newsletter

Keep up to date with industry trends, events and the latest customer stories

Invalid email address

Submit

Great you’re on the list!