-2

を使用して、MVC3 プロジェクトのデフォルトの LogOn 関数を変更して、ユーザーに基づいて特定のページにユーザーをリダイレクトしていましroleUser.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ようにリダイレクトを使用するだけですか?

4

1 に答える 1

0

問題は、LogOn関数が呼び出されたときに、着信要求に認証されたユーザーがなく、User オブジェクトが null であり、新しい要求が作成されるまで User オブジェクトが入力されないことです。したがって、User.IsInRole()で が呼び出されるとLogOnUserですnull

つまり、User オブジェクトは、要求された ASP.NET ページのコードが実行されるずっと前に、ASP.NET パイプラインの早い段階で設定されます。これで、その後の訪問で、ASP.NET ランタイムはフォーム認証チケットを確認し、User.Identity.IsAuthenticated は true になりますが、この要求ではそうではありません。
...

また、User.Identity.Name からユーザー名を取得することもできません。代わりに、LoginControlID.Username を使用してください。

http://forums.asp.net/post/1988606.aspx

于 2012-08-12T05:51:53.500 に答える