I'm attempting to use Application Request Routing (ARR) in IIS for passing a set of paths to a Node.js website. My issue is being able to get/set the authentication ticket on either side.
I just really need a simple example of an Encrypt/Decrypt pair that will work for C# and Node.js close to out of the box with the same results for both. I'll be working on this problem myself as time permits over the next few days, and intend to answer if nobody comes up with an answer before me.
My intention is to write the node side as a connect/express module on the Node.js side. I am already doing a custom authentication in the ASP.Net solution, and can easily replace my current method with something that can be secure from both platforms (so long as they share the same key).
Current code to create the authentication cookie in AccountController.cs
private void ProcessUserLogin(MyEntityModel db, SiteUser user, bool remember=false)
{
var roles = String.Join("|", value:user.SiteRoles.Select(sr => sr.Name.ToLowerInvariant().Trim()).Distinct().ToArray());
//update the laston record(s)
user.UserAgent = Request.UserAgent;
user.LastOn = DateTimeOffset.UtcNow;
db.SaveChanges();
// Create and tuck away the cookie
var authTicket = new FormsAuthenticationTicket(
1
,user.Username
,DateTime.Now
,DateTime.Now.AddDays(31) //max 31 days
,remember
,string.IsNullOrWhiteSpace(roles) ? "guest" : roles
);
var ticket = FormsAuthentication.Encrypt(authTicket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, ticket);
if (remember) cookie.Expires = DateTime.Now.AddDays(8);
Response.Cookies.Add(cookie);
}
Current code to read the authentication cookie in Global.asax.cs
void Application_AuthenticateRequest(object sender, EventArgs args)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null) return;
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
string[] roles = authTicket.UserData.Split(new Char[] { '|' });
//create new generic identity, and corresponding principal...
var g = new GenericIdentity(authTicket.Name);
var up = new GenericPrincipal(g, roles);
//set principal for current request & thread (app will handle transitions from here)
Thread.CurrentPrincipal = Context.User = up;
}
Relevant portion of the Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<membership>
<providers>
<!-- Remove default provider(s), so custom override works -->
<clear />
</providers>
</membership>
</system.web>
</configuration>