1

再会!

现在这是我项目中的问题。每次我登录它总是在登录页面再次重定向。我试图在我的控制器中放置一个断点,它发生了,当我登录时第一次登录并在我的控制器中单击 f10 它会进入所有状态。但是当我第二次登录时,它会进入控制器以及该帐户的角色。

我的代码:

账户控制人:

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);
                    }
                     if (Roles.IsUserInRole("Employer"))
                    {
                        return RedirectToAction("CustomerIndex", "Customer");
                    }
                     else if (Roles.IsUserInRole("Worker"))
                    {
                        return RedirectToAction("WorkerIndex", "Worker");
                    }
                     else if (Roles.IsUserInRole("Administrator"))
                     {
                         return RedirectToAction("ClientIndex", "Client");
                     }

                }
                else
                {
                    ModelState.AddModelError("", "The user name or password provided is incorrect.");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

登录.cshtml:

@using (Html.BeginForm())
    {
        <div style="width: 500px;">
            <fieldset>
                <legend>Account Information</legend>
                <div class="editor-label" style="padding-top: 20px">
                    @Html.LabelFor(m => m.UserName)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.UserName)
                    @Html.ValidationMessageFor(m => m.UserName)
                </div>
                <div class="editor-label">
                    @Html.LabelFor(m => m.Password)
                </div>
                <div class="editor-field">
                    @Html.PasswordFor(m => m.Password)
                    @Html.ValidationMessageFor(m => m.Password)
                </div>
                <div class="editor-label">
                    @Html.CheckBoxFor(m => m.RememberMe)
                    @Html.LabelFor(m => m.RememberMe)
                </div>
                <p>
                    <input type="submit" value="Log On" class="styledButton" />
                </p>
            </fieldset>
        </div>

    }

谢谢你。:D

4

1 回答 1

1

这是因为在执行该操作时(因为您当时正在登录)尚未在 HttpContext 中设置 User ,因此即使登录的用户属于该角色,对 的调用也Roles.IsUserInRole将全部返回 false 。

假设您正在使用您知道是管理员角色成员的用户登录。LogOn如果您在检查角色以进行重定向之前将以下调试语句添加到您的方法中,您可以自己看到它。

Debug.WriteLine("Controller user name: " + User.Identity.Name);
Debug.WriteLine("HttpContext user name: " + HttpContext.User.Identity.Name);
Debug.WriteLine(Roles.IsUserInRole("Administrator"));

您将在 Visual Studio 的调试输出窗口中看到,即使您已登录并设置了身份验证 cookie,用户名仍将为空,并且 IsUserInRole 将返回 false。

但是,当您再次提交表单时,由于用户已经登录(您只是没有将他重定向到另一个页面),因此现在在 HttpContext 中设置了用户。因此,这次如果您在 LogOn 方法的开头添加这些调试行,您将在输出窗口中看到用户名并且他是管理员。

要解决您的问题,最简单的方法是使用允许您指定用户名的IsUserInRole重载,而不是依赖 HttpContext 用户。您将检查用户角色:

if (Roles.IsUserInRole(model.UserName, "Employer"))
{
    return RedirectToAction("CustomerIndex", "Customer");
}
else if (Roles.IsUserInRole(model.UserName, "Worker"))
{
    ...

您还可以自己创建一个主体并将其设置为 HttpContext.User 在检查用户角色之前:

var curIdentity = new System.Security.Principal.GenericIdentity(model.UserName);
var curPrincipal = new System.Security.Principal.GenericPrincipal(curIdentity, null /*userRoles*/);
HttpContext.User = curPrincipal;
if (Roles.IsUserInRole("Employer"))
{
    return RedirectToAction("CustomerIndex", "Customer");
}
else if (Roles.IsUserInRole("Worker"))
{
    ...

但是我会保持简单,只需将用户名传递给 IsUserInRole 方法。对于应用程序中的任何其他操作,您可以依赖在 HttpContext 中为您自动设置的用户。

于 2013-10-09T09:12:45.790 回答