DCSIMG
WCF – TCP with UserNameToken without Message Security - Zuker On Foundations

Zuker On Foundations

The realm of .NET (WPF, WCF and all around)
WCF – TCP with UserNameToken without Message Security

There was a project that I assisted with the WCF communications where they needed to allow the client to specify different credentials without being dependent on the windows account.

The first thing that comes into mind is to use the UserNameToken technique to pass in the client credentials. The design instructed to use TCP as the transport and not use message security. Obviously, this technique has privacy and integrity issues where there isn’t any encryption nor signing, but that was their decision because it wasn’t an issue in the purpose of the project.

Well, this setting isn’t as trivial as you would expect.
The default form of the NetTcpBinding allows you to use UserNameToken only as part of message security and forces you to use a certificate to enable that message security.

I ended up setting them a CustomBinding which provides the scenario they needed.

Service Side

Configuring the Service Host -

Code Snippet
  1. _host = new ServiceHost(typeof(Service));
  2. _host.AddServiceEndpoint(typeof(IService), Config.ServiceBinding, Config.ServiceAddress.Uri.AbsoluteUri);
  3.  
  4. _host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
  5. _host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameTokenValidator();
  6.  
  7. _host.Open();

Custom Simple Validator (you can write any logic you need here) -

Code Snippet
  1. class CustomUserNameTokenValidator : UserNamePasswordValidator
  2. {
  3.     public override void Validate(string userName, string password)
  4.     {
  5.         Console.WriteLine("CustomUserNameTokenValidator.Validate - {0} / {1}", userName, password);
  6.  
  7.         if (string.IsNullOrEmpty(userName))
  8.         {
  9.             throw new SecurityTokenValidationException("Invalid username");
  10.         }
  11.     }
  12. }

In the service code, you can extract the caller’s identity name as follows -

Code Snippet
  1. class Service : IService
  2. {
  3.     public void Do()
  4.     {
  5.         Console.WriteLine("Service.Do() - Identity Name: {0}",
  6.             ServiceSecurityContext.Current.PrimaryIdentity.Name);
  7.     }
  8. }

Client Side

In the client side you need to use the same binding, provide the UserNameToken credentials and simply call the service -

Code Snippet
  1. ChannelFactory<IService> factory = new ChannelFactory<IService>(Config.ServiceBinding, Config.ServiceAddress);
  2. factory.Credentials.UserName.UserName = "myUser";
  3. factory.Credentials.UserName.Password = "myPassword";
  4.  
  5. IService proxy = factory.CreateChannel();
  6.  
  7. proxy.Do();
  8.  
  9. ((ICommunicationObject)proxy).Close();

Configuration

Following is the CustomBinding which enables this scenario -

Code Snippet
  1. SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
  2. ((TransportSecurityBindingElement)securityElement).AllowInsecureTransport = true;
  3.  
  4. _serviceBinding = new CustomBinding(new BindingElement[] {
  5.     securityElement,
  6.     new BinaryMessageEncodingBindingElement(),
  7.     new TcpTransportBindingElement()
  8. });

Feel free to download the source code and see that in action.

Published Sunday, November 07, 2010 1:41 PM by Amir Zuker

תגים:,

Comments

# re: WCF – TCP with UserNameToken without Message Security@ Sunday, November 07, 2010 10:07 PM

Customers that still use Wcf 3.5 can do the same "trick" as in ClearUsernameBinding:

code.google.com/.../wcf-clear-username-binding

Yaron Naveh

# re: WCF – TCP with UserNameToken without Message Security@ Monday, November 08, 2010 7:33 AM

Thanks for pointing that out Yaron.

Seems a bit overshoot in this case though, since you can do it using plain vanilla WCF as in the example.

Amir Zuker

Amir Zuker

# re: WCF – TCP with UserNameToken without Message Security@ Monday, November 08, 2010 12:10 PM

Amir - this is only available from .Net 4.0. In .Net 3.5 this was not available. There was a hotfix over .Net 3.5 SP1 which added this capability but it had a few problems.

Yaron Naveh

# re: WCF – TCP with UserNameToken without Message Security@ Monday, November 08, 2010 1:18 PM

Thanks for clearing that out Yaron.

Amir Zuker

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: