Introduction
Selfhosted Secure WCF Custom validation, No config file needed – all setting in code only, No IIS – Self hosted, consume by channel factory
Background
I recently came in situation where I need to make Secure WCF POC in environment where we don’t have IIS and we have only VS 2010 Express. And we need to create totally self dependent POC so no certificate.
The solution is to create self hosted WCF service use custom validation and consume it by using Channel factory. While create this POC I got some error then I started searching internet for similar kind of POC I got couple of them but most of them Is not in ready to run position like have only server side code or have only client or need to change something in app.config.<o:p>
WCF Server side
Self hosted (console) WCF service, Transport security (ID/Pwd)
using System;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.IdentityModel.Tokens;
using System.IdentityModel.Selectors;
using System.Security.Principal;
using System.ServiceModel.Description;
namespace SecurWCFSelfHosting
{
class Program
{
[ServiceContract]
public interface IDemoService
{
[OperationContract]
int Add(int x, int y);
}
public class DemoService : IDemoService
{
public int Add(int x, int y)
{
return x + y;
}
}
static void Main(string[] args)
{
Uri httpUrl = new Uri("http://localhost:999/MyService/");
ServiceHost host = new ServiceHost(typeof(DemoService), httpUrl);
BasicHttpBinding http = new BasicHttpBinding();
http.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
http.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
host.AddServiceEndpoint(typeof(IDemoService), http, "");
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new MyCustomValidator();
ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
{
smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
}
host.Open();
Console.WriteLine(DateTime.Now.ToString()+" Service is host at " + httpUrl.ToString());
Console.WriteLine("The service is running in the following account: {0}", WindowsIdentity.GetCurrent().Name);
Console.WriteLine("Press <ENTER> to terminate service.");
Console.ReadLine();
}
}
public class MyCustomValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if ((userName != "h") || (password != "p"))
{
throw new SecurityTokenException("Him:) Validation Failed!");
}
Console.WriteLine(DateTime.Now.ToString()+" Validation success for user :"+ userName);
}
}
}
Client side
Consume in console apps, using channel factory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace WCFConsumeByChannelFactory
{
class Program
{
static void Main(string[] args)
{
EndpointAddress Serviceaddress = new EndpointAddress("http://localhost:999/MyService/");
BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
ChannelFactory<IDemoService> myChannelFactory =
new ChannelFactory<IDemoService>(httpBinding, Serviceaddress);
var defaultCredentials = myChannelFactory.Endpoint.Behaviors.Find<ClientCredentials>();
myChannelFactory.Credentials.UserName.UserName = "h";
myChannelFactory.Credentials.UserName.Password = "p";
IDemoService wcfClient1 = myChannelFactory.CreateChannel();
double s = wcfClient1.Add(73, 22);
Console.WriteLine(s.ToString());
((IClientChannel)wcfClient1).Close();
Console.ReadKey();
}
}
}
These all code is in attached zip file.
Points of Interest
While searching in internet i found this :How to: Call Operations Asynchronously Using a Channel Factory http://msdn.microsoft.com/en-us/library/bb885132.aspx
Bindings Summary
http://wcfsecurityguide.codeplex.com/releases/view/15892