I am using a cookie and if the cookie is set, it forwards the user to signin, else it shows them an error page (unauthorized). The cookie is being set correctly, and if I navigate to any page by typing it in the address bar, it works just fine. However, when I use RedirectToAction or FormsAuthentication.RedirectToLogin the cookie is not available, which is causing an infinite loop in redirection.
Home - If user has cookie, go to signin, if not show home page.
Signin - If user has cookie, show page, else redirect to home
My redirection is handled through an attribute.
public sealed class RequireBillerAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
IUserSession session = ServiceLocator.Locate<IUserSession>();
if (session.BillerId == 0)
filterContext.Result = new RedirectResult("~/");
}
}
My Home action looks like this
public ActionResult Index()
{
//if the user is signed in, send them to their account page. They don't need to see the front page
if (Request.IsAuthenticated)
{
return RedirectToAction("Index", "Account");
}
//users with their cookie set should sign in
if (session.BillerId != 0)
return RedirectToAction("Index", "SignIn");
return View();
}
And my signin action looks like this
[RequireBiller]
public ActionResult Index()
{
SignInModel model = BuildSignInModel();
return View(model);
}
Now, when I hit mysite.com/ the redirect causes an infinite loop. In debugging, the attribute cannot find the value from the cookie. The cookie is actually blank in the request. When I type mysite.com/signin everything works peachy. Any ideas?
EDIT
As suggested, I ran fiddler. Here's what the requests look like
# Result Protocol Host URL Body Caching Content-Type Process Comments Custom
1 302 HTTP localhost:27412 / 124 private text/html; charset=utf-8 chrome:6008
2 302 HTTP localhost:27412 /SignIn 118 private text/html; charset=utf-8 chrome:6008
3 302 HTTP localhost:27412 / 124 private text/html; charset=utf-8 chrome:6008
4 302 HTTP localhost:27412 /SignIn 118 private text/html; charset=utf-8 chrome:6008
And here is the cookie information
First
__RequestVerificationToken_Lw__=NNu8v2oTMX2YKQOW+JRN1LQRYPhlmPszQa8Rs1KrQp1pPxWmQO8GG7eRrzbhFZF38p05ckuLHAK3QaTIlxeFJ6POTX1woXRx/ahApLpF529inJO9mj3jSnoHqG6fthzJpoLYQL61NOCCUO2wwzLmQg==; 4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*=P%2ffJD5CdLO0pCGU6GntaPw*=P6QAytlDVUrkQn84c9vDVg*
Second
4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*=; __RequestVerificationToken_Lw__=NNu8v2oTMX2YKQOW+JRN1LQRYPhlmPszQa8Rs1KrQp1pPxWmQO8GG7eRrzbhFZF38p05ckuLHAK3QaTIlxeFJ6POTX1woXRx/ahApLpF529inJO9mj3jSnoHqG6fthzJpoLYQL61NOCCUO2wwzLmQg==; 4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*=P%2ffJD5CdLO0pCGU6GntaPw*=P6QAytlDVUrkQn84c9vDVg*
Third
__RequestVerificationToken_Lw__=NNu8v2oTMX2YKQOW+JRN1LQRYPhlmPszQa8Rs1KrQp1pPxWmQO8GG7eRrzbhFZF38p05ckuLHAK3QaTIlxeFJ6POTX1woXRx/ahApLpF529inJO9mj3jSnoHqG6fthzJpoLYQL61NOCCUO2wwzLmQg==; 4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*=P%2ffJD5CdLO0pCGU6GntaPw*=P6QAytlDVUrkQn84c9vDVg*
Fourth
4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*=; __RequestVerificationToken_Lw__=NNu8v2oTMX2YKQOW+JRN1LQRYPhlmPszQa8Rs1KrQp1pPxWmQO8GG7eRrzbhFZF38p05ckuLHAK3QaTIlxeFJ6POTX1woXRx/ahApLpF529inJO9mj3jSnoHqG6fthzJpoLYQL61NOCCUO2wwzLmQg==; 4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*=P%2ffJD5CdLO0pCGU6GntaPw*=P6QAytlDVUrkQn84c9vDVg*
And here's what it looks like when I type in /signin into the address bar
__RequestVerificationToken_Lw__=NNu8v2oTMX2YKQOW+JRN1LQRYPhlmPszQa8Rs1KrQp1pPxWmQO8GG7eRrzbhFZF38p05ckuLHAK3QaTIlxeFJ6POTX1woXRx/ahApLpF529inJO9mj3jSnoHqG6fthzJpoLYQL61NOCCUO2wwzLmQg==; 4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*=P%2ffJD5CdLO0pCGU6GntaPw*=P6QAytlDVUrkQn84c9vDVg*
Yes, my cookies are encrypted. The cookiename is "4%40f0nkyBbqcTD4g9yl1J8KDNcWdqRpixrEoHLuMP2Lc*" It seems to me the redirect is appending a new empty cookie in there. WHY? I'm not sure.
ADDITIONAL After debugging, I have found that indeed there are 3 cookies in the Request. The first is the empty cookie, which is returned by default when using the name. The third cookie in the collection has the values set. Why it is appending this cookie into the request is a mystery. I can probably work around this by picking the cookie that has a value over the other one, but I'd rather fix the root issue, whatever it is, that is happening only on the signin page.
I think what's happening is that RedirectToAction is doing a Response.Redirect() which is terminating the processing of the request and not allowing the cookie to be set. Sounds like a similar problem to what is documented here for session:
http://weblogs.asp.net/bleroy/archive/2004/08/03/207486.aspx