WCF and Forms authentication
This is about flowing ASP.NET Forms authentication to WCF service. Once successfully authenticated, forms authentication data is stored as an encrypted cookie. And since the encryption is machine dependent its important to have the validationKey and decryptionKey same in both the web.configs(web app and WCF app).
Check this MSDN link to know more about configuring machineKey for asp.net forms authentication.
http://msdn.microsoft.com/en-us/library/ms998288.aspx
1.)Create a validationkey and decryptionkey. Run the below program two times. The value generated first time can be used as the validationKey and the second one machineKey in the web.configs.
static void Main(string[] args)
{
int len = 48;
byte[] buff = new byte[len / 2];
RNGCryptoServiceProvider rng = new
RNGCryptoServiceProvider();
rng.GetBytes(buff);
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < buff.Length; i++)
sb.Append(string.Format("{0:X2}", buff[i]));
Console.WriteLine(sb);
}
2.) Configure the web.configs(wcf and web app) to use the generated keys as follows.
<system.web/>
<machineKey validationKey="D4E763ABFD89DAAD50620E89E11FFAB7AD94AF9EDE264526" decryptionKey="5F0A4D7396E35CF534F0B404F481CA70C2C5A43071729BE4" decryption="3DES"/>
</span>
3.)Configure the WCF service to run in ASP NET compatibility mode.
This is to be done in two place. One in wcf service web.config as follows
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
And
in the service behaviour
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
4.)Configure forms authentication in asp.net config
<authentication mode="Forms">
<forms name="appNameAuth" path="/" loginUrl="login.aspx" protection="All" timeout="30">
<credentials passwordFormat="Clear">
<user name="jeff" password="test" />
<user name="mike" password="test" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
5.)In login.aspx
if (FormsAuthentication.Authenticate(txtUser.Text, txtPassword.Text))
FormsAuthentication.RedirectFromLoginPage(txtUser.Text, chkPersistLogin.Checked);
else
ErrorMessage.InnerHtml = "Something went wrong... please re-enter your credentials...";
This sets the authentication cookie on successful login.
6.)Now send the cookie in WCF request http header
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);
}
7.)At the service side you can read the cookie inside the operation as follows
HttpRequestMessageProperty g = OperationContext.Current.IncomingMessageProperties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
string s = g.Headers.Get(HttpRequestHeader.Cookie.ToString());
FormsAuthenticationTicket tick = FormsAuthentication.Decrypt(s);
Working Sample
http://cid-05c2e50f2c5140c1.skydrive.live.com/self.aspx/.Public/WCFFormsAuthentication.rar
This article is taken from my blog
Reference: http://thoughtorientedarchitecture.blogspot.com/
Hi Hari,
This article was a great help to me.
I exactly needed the same info!!
Thanks a ton!!:)
Regards,
Lavanya