Securing WCF with Forms Authentication
In this post i will explain how to secure Rest ful Service without SSL Certificate, i just apply form authentication in these. first and new WCF Service Application in VS 2010.
Create new service ILoginService like these-
[ServiceContract]
public interface ILoginService
{
[OperationContract]
bool Login(string userName, string password);
}
Now i am using entity framework for authenticate user that's way i have added one edmx file like these-

in that database i have two tables one is UserTable and another is tblEmployee.
Now i need to implemented method in Loginservice like these-
In these page i validate user with the help of entity framework method and create AuthTicket with user information and after that we encrypt the user information and add to cookie.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,IncludeExceptionDetailInFaults=true)]
public class LoginService : ILoginService
{
TestEntities db = new TestEntities(); //Edmx context reffrence
public bool Login(string userName, string password)
{
bool returnValue = false;
UserTable user;
using (var ctx = new TestEntities())
{
user = ctx.UserTables.Where(one => one.UserName == userName).FirstOrDefault();
if (user != null)
{
returnValue = (user.Password == password);
}
}
if (returnValue)
{
//Create Authentic ticket for user
var AutTicket = new FormsAuthenticationTicket(
1,
userName,
DateTime.Now,
DateTime.Now.AddDays(1),
true,
user.Id.ToString()
);
// Encrypt user detail
string encryptedTicket = FormsAuthentication.Encrypt(AutTicket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
// Add Encrypt detail in to cookie.
HttpContext.Current.Response.Cookies.Add(cookie);
}
return returnValue;
}
}
Now add one class RestService.cs for define method for Restful Service like these -
//Return string
[WebGet(UriTemplate = "/GetTest", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public string GetTest()
{
return "test";
}
//Return XElement
[WebInvoke(Method = "POST", UriTemplate = "/CaptureTest", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
public XElement CaptureTest(XElement x)
{
// For get the encrypted value from request
string testcookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName].Value;
//Now Decrypt the cookie and get the user detail
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(testcookie);
return XElement.Parse("<Result>xml captured</Result>");
}
Now in WCFRestService web.config file-
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="TestEntities" connectionString="metadata=res://*/WCFModel.csdl|res://*/WCFModel.ssdl|res://*/WCFModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.;Initial Catalog=Test;User ID=sa;Password=server;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
<authentication mode="Forms">
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
<location path="LoginService.svc">
<system.web>
<authorization>
<allow users="?" />
</authorization>
</system.web>
</location>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
</system.webServer>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
RestFulService work is end here.now i want to consume that service in my WebApplication.
Add New website then Add Service Reference in that application now in one webpage i have tried to access that service i have write that code on page-load event for test-
protected void Page_Load(object sender, EventArgs e)
{
var Cookie = string.Empty;
bool isValid;
string data = string.Empty;
var userAuth= new LoginServiceClient(); //that comes from service refrence
using (new OperationContextScope(authClient.InnerChannel))
{
isValid = userAuth.Login("username", "password");
if (isValid)
{
var response = (HttpResponseMessageProperty)OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name];
Cookie = response.Headers["Set-Cookie"];
}
if (isValid)
{
// For Capture Test check
var request = (HttpWebRequest)WebRequest.Create("http://localhost:48090/RestService/CaptureTest");
request.Timeout = 30000;
request.Method = "POST";
request.ContentType = "text/xml";
request.Headers["Cookie"] = Cookie;
var xmlDoc = new XmlDocument { XmlResolver = null };
xmlDoc.Load(Server.MapPath("PostData.xml"));
string sXml = xmlDoc.InnerXml;
request.ContentLength = sXml.Length;
var sw = new StreamWriter(request.GetRequestStream());
sw.Write(sXml);
sw.Close();
HttpWebResponse res = null;
var tst = request.GetResponse();
res = (HttpWebResponse)request.GetResponse();
Stream responseStream = res.GetResponseStream();
var streamReader = new StreamReader(responseStream);
string str = string.Empty;
str = streamReader.ReadToEnd();
//End Capture Test
// For GetTest Method
var request2 = (HttpWebRequest)WebRequest.Create("http://localhost:48090/RestService/GetTest");
request2.Headers["Cookie"] = Cookie;
var responce2 = request2.GetResponse();
using (var stream = responce.GetResponseStream())
{
using (var reader = new StreamReader(stream))
{
data = reader.ReadToEnd();
Console.Write(data);
}
}
}