Windows Communication Foundation (WCF) is a framework for distributed application. WCF is the easiest way to produce and consume Web services on the Microsoft platform. The mechanism of WCF operation is similar to ASP.NET web services (WS). Clients can invoke and consume multiple services, and a single service can be consumed by multiple clients. web services -Addressing, web services -Reliable Messaging and web services -Security are some of the Web Services specifications that are implemented by WCF. Now with this article shows how to secure a Windows Communication Foundation (WCF) service with Forms Authentication.

So, here is to enable the authentication service :
- use built-in template in Visual Studio 2010
- Create authentication WCF Service
- Create Data WCF RESTful serviceCreate some basic functionality to perform CRUD operations on a Person object.
- Create users table I am going to use for authentication.
write the following code for operational RESTful service
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using System.Web.Script.Services;
namespace CustomWcfRestService
{
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class CustomService
{
[WebGet(UriTemplate = "/GetPeople", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public List<Person> GetPeople()
{
using(var ctx = new Context())
{
ctx.Configuration.LazyLoadingEnabled = false;
ctx.Configuration.ProxyCreationEnabled = false;
return ctx.People.OrderBy(one => one.LastName).ThenBy(two => two.FirstName).ToList();
}
}
[WebInvoke(UriTemplate = "/Create", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public Person Create(Person person)
{
using (var ctx = new Context())
{
ctx.Entry(person).State = EntityState.Added;
ctx.SaveChanges();
return person;
}
}
[WebGet(UriTemplate = "/GetPerson?id={id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public Person Get(int id)
{
using (var ctx = new Context())
{
ctx.Configuration.LazyLoadingEnabled = false;
ctx.Configuration.ProxyCreationEnabled = false;
return ctx.People.Find(id);
}
}
[WebInvoke(UriTemplate = "/UpdatePerson", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public Person Update(Person person)
{
using (var ctx = new Context())
{
ctx.Entry(person).State = EntityState.Modified;
ctx.SaveChanges();
return person;
}
}
[WebInvoke(UriTemplate = "/GetPerson?id={id}", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public void Delete(int id)
{
using (var ctx = new Context())
{
var person = new Person {ID = id};
ctx.Entry(person).State = EntityState.Deleted;
ctx.SaveChanges();
}
}
}
}
- LoginService that I will use for authentication. Configure forms authentication in asp.net config
using System;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web.Security;
using System.Web;
namespace CustomWcfRestService
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class LoginService : ILoginService
{
public bool Login(string userName, string password)
{
bool returnValue = false;
User user;
using (var ctx = new Context())
{
user = ctx.Users.Where(one => one.UserName == userName).FirstOrDefault();
if (user != null)
{
returnValue = (user.Password == password);
}
}
if (returnValue)
{
var ticket = new FormsAuthenticationTicket(
1,
userName,
DateTime.Now,
DateTime.Now.AddDays(1),
true,
user.UserID.ToString()
);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
HttpContext.Current.Response.Cookies.Add(cookie);
}
return returnValue;
}
}
}
- Below Configure forms authentication in asp.net config is sample web.config configuration for enable actual security.
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="SecuredServiceDemo"
connectionString="Server=.;Integrated Security=SSPI;Database=SecuredServiceDemo"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Forms">
</authentication>
<authorization>
<deny users="?"/>
</authorization>
</system.web>
<location path="LoginService.svc">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
- And The last create a test client, create validate credentials against database. creating custom cookie, encrypting it and sending back to the client.
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers.Add(HttpRequestHeader.Cookie, FormsAuthentication.GetAuthCookie(User.Identity.Name, false).Value);
ServiceReference1.Service1Client serviceClient = new WebApplication1.ServiceReference1.Service1Client();
using (OperationContextScope scope = new OperationContextScope(serviceClient.InnerChannel)){
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
string s =serviceClient.GetData(2);}
At the service side
HttpRequestMessageProperty g = OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
string s = g.Headers.Get(HttpRequestHeader.Cookie.ToString());
FormsAuthenticationTicket tick = FormsAuthentication.Decrypt(s);
There are many ways to authenticate and authorize a user in a WCF Service, but in this example, the authentication cookie will already be created by the login page and that will be used by subsequent requests made to the REST service for authorization. This is it to secure <a href="http://asphostportal.com/ASPNET-451-Hosting">ASP.NET 4.5.1 Hosting</a> Windows Communication Foundation (WCF) service with Forms Authentication
Just to confirm that everything is working, I can just comment out the part that authenticates and gets a cookie, and I get 404 as expected. Once authenticated, a "session" is kept to hold on to security related info like the roles of a user.
Happy coding :)