ASP.NET MVC中Edit页面RedirectToAction跳转至登录页问题排查
问题现象
在ASP.NET MVC应用中,Edit页面执行POST提交后,调用RedirectToAction("Index")未跳转到Index页面,反而重定向至登录页;重新登录后可正常跳转。登录时生成认证Cookie,点击保存按钮前Cookie无变化,触发登录提示并重新登录后Cookie值才更新,且未主动修改过Cookie。
相关代码
Edit POST Action(含角色验证版本)
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(SampleVM samplevm) { if (!IsUserInAuthorizedRole()) { return View("~/Views/Shared/Unauthorized.cshtml"); } if (ModelState.IsValid) { samplevm.UserId = User.Identity.Name; Sample sample = PopulateSample(samplevm); db.Entry(sample).State = EntityState.Modified; db.SaveChanges(); TempData["Message"] = "Sample has been updated."; return RedirectToAction("Index"); } return View(samplevm); }
其他相关Action
// POST Create [HttpPost] [ValidateAntiForgeryToken] public JsonResult SaveSamples(SampleVM samplevm) { bool status = false; if (ModelState.IsValid) { var lotExists = SampleExists(samplevm.LotId); if(lotExists) { return Json(new { success = false , status = status , responseText = "LotId " + samplevm.LotId + " already exists." }, JsonRequestBehavior.AllowGet); } samplevm.UserId = User.Identity.Name; Sample sample = PopulateSample(samplevm); db.Samples.Add(sample); db.SaveChanges(); int sampleId = sample.SampleId; status = true; return Json(new { success = true , redirectUrl = Url.Action("Index", "Samples") , status = status, responseText = "Sample has been saved" }, JsonRequestBehavior.AllowGet); } return new JsonResult { Data = new { status = status } }; } // POST Edit(无角色验证版本) [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit(SampleVM samplevm) { if (ModelState.IsValid) { samplevm.UserId = User.Identity.Name; Sample sample = PopulateSample(samplevm); db.Entry(sample).State = EntityState.Modified; db.SaveChanges(); TempData["Message"] = "Sample has been updated."; return RedirectToAction("Index"); } return View(samplevm); }
排查与解决方向
优先验证身份有效性而非仅角色
检查IsUserInAuthorizedRole()方法,是否只验证角色而未先确认用户是否已认证。如果会话超时但User.Identity.IsAuthenticated仍为true(Cookie已失效但客户端未更新),会导致执行完数据库操作后,重定向时才触发认证检查。建议在Action开头先判断:if (!User.Identity.IsAuthenticated) { return RedirectToAction("Login", "Account"); } if (!IsUserInAuthorizedRole()) { return View("~/Views/Shared/Unauthorized.cshtml"); }检查Forms认证Cookie配置
打开Web.config,确认Forms认证的timeout和slidingExpiration设置:<authentication mode="Forms"> <forms loginUrl="~/Account/Login" timeout="2880" slidingExpiration="true" /> </authentication>slidingExpiration="true"会在每次活跃请求时延长Cookie有效期,避免编辑操作过程中超时;确保timeout值足够覆盖正常操作时长。同步Session与认证超时时间
TempData依赖Session,如果Session超时时间短于Forms认证Cookie超时,会导致重定向时Session失效,间接触发认证检查。检查Session配置:<sessionState mode="InProc" timeout="2880" />让Session超时时间与Forms认证保持一致。
排查Cookie是否被意外修改
用浏览器F12开发者工具,查看Edit请求的Request Headers里的Cookie值,以及响应的Response Headers是否有Set-Cookie头。如果服务器在响应中发送了新的认证Cookie,说明有逻辑在修改Cookie,需要排查全局过滤器、安全组件或其他请求处理代码。验证Anti-Forgery Token有效性
Anti-Forgery Token与当前认证会话绑定,如果Cookie过期,Token会失效。可以在Edit页面加载时,确保Token是基于有效会话生成的;也可以添加全局认证过滤器,提前拦截未认证请求,避免执行完业务逻辑后才重定向登录。
内容的提问来源于stack exchange,提问作者Eric

