繁体   English   中英

成功登录后,用户未经过身份验证

[英]User isn't authenticated after successful login

我使用Visual Studio中的默认自动生成的登录/密码模板创建了一个ASP.NET MVC应用程序。

如果我没有登录,我有一些[授权]操作正确地将我重定向到登录表单。当我尝试使用错误的密码登录时,我得到了预期的错误。 然后,当我尝试正确的用户名和密码时,我没有收到任何错误,但我仍然无法访问[授权]操作。 应用程序在Login窗体中不断重定向,因为Return_url是我的[Authorize]操作。 我添加了User.Identity.Name的显示,它总是空白的。

我做的第一件事就是像这样更改Login.cshtml:

@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <div style="text-align:center; margin-top:10px">
        <h3>Log In</h3>
    </div>
    <hr />
    <div style="margin-left:10px">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    </div>
    <div style="margin-left:50px">
        <div class="form-group">
            @Html.LabelFor(m => m.User, new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.TextBoxFor(m => m.User, new { placeholder = "Username", @class = "form-control" })
                @Html.ValidationMessageFor(m => m.User, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
            <div class="col-md-10">
                @Html.PasswordFor(m => m.Password, new { placeholder = "Password", @class = "form-control" })
                @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <div class="checkbox">
                    @Html.CheckBoxFor(m => m.RememberMe)
                    @Html.LabelFor(m => m.RememberMe)
                </div>
            </div>
        </div>
    </div>
    <div style="margin-left:25px">
        <div class="form-group">
            <div class="col-md-12">
                <input type="submit" value="Connect" class="btn btn-primary btn-lg btn-block" />
            </div>
        </div>
    </div>
}

我还修改了LoginViewModel,如下所示:

public class LoginViewModel
{
    [Required]
    [Display(Name = "User")]
    [DataType(DataType.Text)]
    public string User { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }
}

之后,我修改了在HttpPOST请求上调用的ActionResult Login:

// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var result = SignInManager.CustomPasswordSignIn(model.User, model.Password, model.RememberMe, shouldLockout: false);
    switch (result)
    {
        case CustomSignInStatus.Success:
            return RedirectToLocal(returnUrl);
        case CustomSignInStatus.Admin:
            return RedirectToLocal(returnUrl);
        case CustomSignInStatus.LockedOut:
            return View("Lockout");
        case CustomSignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, model.RememberMe });
        case CustomSignInStatus.Satellite_fail:
            ModelState.AddModelError("", "Satellite failed.");
            return View(model);
        case CustomSignInStatus.Failure:
        default:
            ModelState.AddModelError("", "Incorrect login or password.");
            return View(model);
    }

因为我需要更多登录情况(Success,Admin,LockedOut,RequiresVerification,Satellite_fail,Failure),我创建了一个CustomSignInStatus:

public enum CustomSignInStatus
    {
        //
        // Summary:
        //     Sign in was successful
        Success = 0,
        //
        // Summary:
        //     User is locked out
        LockedOut = 1,
        //
        // Summary:
        //     Sign in requires addition verification (i.e. two factor)
        RequiresVerification = 2,
        //
        // Summary:
        //     Sign in failed
        Failure = 3,
        //
        // Summary:
        //     Satellite sign in failed
        Satellite_fail = 4,
        //
        // Summary:
        //     Admin sign in
        Admin = 5
    }

然后我必须实现我自己的CustomPasswordSignIn来使用我的CustomSignInStatus,如下所示:

public CustomSignInStatus CustomPasswordSignIn(string userName, string password, bool isPersistent, bool shouldLockout)
        {
            string hashpwd = Tools.HashData(password);

            if (userName == "admin" && hashpwd == ConfigurationManager.AppSettings["ADMIN"]) return CustomSignInStatus.Admin;

            using (IDal dal = new Dal())
            {
                int sat = dal.GetSatellite();

                if (sat == -1) return CustomSignInStatus.Satellite_fail;

                if (dal.CheckLogs(userName, hashpwd, sat)) return CustomSignInStatus.Success;
            }

            return CustomSignInStatus.Failure;
        }

此方法哈希输入密码,验证用户是否为管理员,然后尝试验证Satellite和夫妇登录/密码。

此时,身份验证似乎正在运行,但没有创建会话,用户未经过身份验证,因此无法访问[授权]操作。 我想我必须在某处添加会话创建但我无法找到代码中缺少的内容。 成功登录后如何验证用户身份?

我发现了如何解决我的问题:

在AccountController中,在Login Action和从SignInManager.CustomPasswordSignIn调用的结果切换内部,我编辑了这样的情况:

case CustomSignInStatus.Admin:
    adm = true;
    goto case CustomSignInStatus.Success;
case CustomSignInStatus.Success:

    var claims = new List<Claim>
    {
        new Claim(ClaimTypes.Name, model.User)
    };
    if (adm) claims.Add(new Claim(ClaimTypes.Role, "Administrator"));
    var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

    var ctx = Request.GetOwinContext();
    var authenticationManager = ctx.Authentication;
    authenticationManager.SignIn(id);

    return RedirectToLocal(returnUrl);

现在我的用户被正确识别并可以访问[授权]操作。

如果您正在使用FormsAuthentication,那么当用户验证时,您需要在FormsAuthentication中使用SetAuthCookie

case CustomSignInStatus.Success:
FormsAuthentication.SetAuthCookie(model.User, model.RememberMe);
return RedirectToLocal(returnUrl);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM