を使用して、MVC3 プロジェクトのデフォルトの LogOn 関数を変更して、ユーザーに基づいて特定のページにユーザーをリダイレクトしていましrole
たUser.IsInRole()
。私がこれをテストしていたとき、最初の数人のユーザーは期待どおりにリダイレクトされましたが、その後、本来あるべき場所にリダイレクトされなかった数人のユーザーがいました (彼らはすべてのステートメントを通過し、デフォルトのホーム インデックスにヒットしました)。完全にランダムでadmin
、管理ページに移動する場合もあれば、そうでない場合もあります。
私のログオン機能:
[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
、ユーザーは認証されたようですが、どうやら認証されていないようです。
では、afterMembership.ValidateUser()
が呼び出された時点で、User.IsInRole()
going は正しく機能するのでしょうか? クッキーがドロップされた後ですか、それとも何ですか?
if(Roles.IsUserInRole(model.UserName, "Admin"))
提出されたモデルのユーザー名を持っているので、使用できると思います。これはより良いアイデアだと思いますか、それとも私のSorting
ようにリダイレクトを使用するだけですか?