我正在更改MVC3项目中的默认LogOn函数,以使用role
将用户重定向到基于User.IsInRole()
的某个页面。当我测试这个时,前几个用户按预期重定向,但之后我有一对没有重定向到他们应该的位置(他们通过所有语句并点击默认的主页索引。)似乎完全随机,有时我的admin
将被带到管理页面,有时则没有。
我的LogOn功能:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if(ModelState.IsValid)
{
if(Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if(Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 &&
returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") &&
!returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
{
if(User.IsInRole("Admin") || User.IsInRole("SuperAdmin"))
{
return RedirectToAction("Index", "Admin");
}
else if(User.IsInRole("Employee"))
{
return RedirectToAction("Index", "Employee");
}
else if(User.IsInRole("Accounting"))
{
return RedirectToAction("Index", "Accounting");
}
// If the user is in none of those roles, send them to the home index
return RedirectToAction("Index", "Home");
}
}
else
{
MembershipUser user = Membership.GetUser(model.UserName);
if(user == null)
ModelState.AddModelError("", "The user name or password provided is incorrect.");
else
ModelState.AddModelError("", "You haven't been approved yet, or you are locked out.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
看看IntelliTrace,似乎有时它不会费心去查询数据库,例如,当它工作时我会看到Execute Reader "dbo.aspnet_UsersInRoles_GetRolesForUser"
,而当它不存在时我就不会这样做。
有人知道为什么即使用户在角色中,User.IsInRole()
会返回false吗?是否有某种形式的兑现发生,为什么不是每次都在为数据库排队?
我肯定知道用户是我正在测试的角色,而且我知道它并没有尝试重定向到返回URL,我也知道该角色没有存储在任何cookie中。任何想法都会受到赞赏,我相信我可以采用另一种方式,但现在我更感兴趣的是为什么这种简单的方法不起作用。
更新
我发现如果我将If(User.IsInRole(...
语句替换为另一个名为排序的操作,并在那里添加if语句,它会100%有效。
public ActionResult Sorting()
{
if(User.IsInRole("Admin") || User.IsInRole("SuperAdmin"))
{
return RedirectToAction("Index", "Admin");
}
else if(User.IsInRole("Employee"))
{
return RedirectToAction("Index", "Employee");
}
else if(User.IsInRole("Accounting"))
{
return RedirectToAction("Index", "Accounting");
}
// If the user is in none of those roles, send them to the home index
return RedirectToAction("Index", "Home");
}
显然User.Identity.Name
未设置(或不会返回用户名),直到LogOn
函数退出。它是否正确?我想在调用Membership.ValidateUser
后,用户已经过身份验证,显然不是。
那么在调用Membership.ValidateUser()
之后的某个时刻,User.IsInRole()
会正常工作吗?是在cookie掉线后,还是什么?
我想我可以使用if(Roles.IsUserInRole(model.UserName, "Admin"))
因为我确实拥有提交模型的用户名。您认为这是一个更好的主意,还是像我一样使用Sorting
重定向?
答案 0 :(得分:0)
问题是,当调用LogOn
函数时,传入请求没有经过身份验证的用户,User对象为null,直到新请求填充User对象为止。因此,当User.IsInRole()
中调用LogOn
时,User
为null
。
简而言之,用户对象是早期在ASP.NET管道中设置的 在执行请求的ASP.NET页面代码之前。现在,关于 随后访问,ASP.NET运行时将看到表单 身份验证票证和User.Identity.IsAuthenticated将为true, 但不是这个要求。
...此外,您将无法获得用户名 来自User.Identity.Name。而是使用LoginControlID.Username。