MVC控制器和身份2.1 -从注册方法意外跳转到登录方法

本文关键字:方法 意外 登录 注册 控制器 身份 MVC | 更新日期: 2023-09-27 17:50:51

在我的代码中,我作为超级管理员登录,并试图将用户注册到系统中,使用Identity 2.1作为我的授权系统。提交表单时,我得到一个HTTP 302重定向并发送到登录屏幕。我不明白为什么。

I have check:

  • 表单中所有ViewModel属性的存在(或使它们为空),除了密码,因为这些属性稍后会通过电子邮件发送出去
  • 控制器上的授权属性匹配我在浏览器中的台架测试

谁能解释一下为什么这个重定向还在继续?

控制器代码:

 // POST: /Account/Register
    [HttpPost]
    [Authorize(Roles = "SuperAdmin")]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        model.BackgroundOnFile = false;
        if (ModelState.IsValid)
        {
            var userDetails = new ApplicationUser { 
                Id = model.Id, 
                UserName = model.Email, 
                Title = model.Title, 
                Email = model.Email, 
                FirstName = model.FirstName, 
                LastName = model.LastName, 
                LEAID = model.LEAID, 
                SchoolID = model.SchoolID, 
                BackgroundOnFile = model.BackgroundOnFile, 
                BoardStart = model.BoardStart.Value, 
                BoardEnd = model.BoardEnd.Value, 
                PhoneNumber = model.PhoneNumber, 
                IsBoardChair = model.IsBoardChair, 
                IsBoardMember = model.IsBoardMember, 
                IsAccountActive = model.IsAccountActive 
            };

            //Keeping old query to allow for future address capture
            /*
            var userDetails = new ApplicationUser { UserName = model.Email, Title = model.Title, Email = model.Email, FirstName = model.FirstName, LastName = model.LastName, LEAID = model.LEAID, SchoolID = model.SchoolID, Address1 = model.Address1, Address2 = model.Address2, City = model.City, State = model.State, PostCode = model.PostCode, BackgroundOnFile = model.BackgroundOnFile, BoardStart = model.BoardStart, BoardEnd = model.BoardEnd, PhoneNumber = model.PhoneNumber, IsBoardChair = model.IsBoardChair, IsBoardMember = model.IsBoardMember };*/
            //Declaring in Scope
            var result = new IdentityResult();
            //Process if new
            if(model.Id == "" || model.Id == "undefined" || model.Id == "null" || model.Id == "-9999")
            {
                model.Password = "Donec hendrerit tortor sed@$!11212";
                result = await UserManager.CreateAsync(userDetails, model.Password);
                var getPassword = new ForgotPasswordViewModel
                {
                    Email = model.Email
                };
                //Email PW
                await ForgotPassword(getPassword);
            }
            //Process if update
            if (model.Id != "" || model.Id != "undefined" || model.Id != "null" || model.Id != "-9999")
            {
                result = await UserManager.UpdateAsync(userDetails);
            }

            //Process Roles
            //Remove access if deactivated
            if (model.IsAccountActive == false)
            {
                var user = await UserManager.FindByIdAsync(userDetails.Id);
                await UserManager.RemoveFromRolesAsync(userDetails.Id, UserManager.GetRoles(userDetails.Id).ToArray());
                await UserManager.AddToRoleAsync(userDetails.Id, "Deactivated");
                userDetails.LockoutEnabled = true;
                await UserManager.UpdateAsync(userDetails);
            }
            else
            {
                //Moved to separate controller, for safety Admin rights can only be done for existing users
                if(model.LEAAdmin == true)
                {
                    await UserManager.AddToRoleAsync(userDetails.Id, "LEAAdmin");
                }
                //LEAAdmin is higher level, so don't allow override to a lower level
                if(model.IsBoardChair == true && model.LEAAdmin == false)
                {
                    await UserManager.AddToRoleAsync(userDetails.Id, "SchoolAdmin");
                }
                else
                {
                    await UserManager.AddToRoleAsync(userDetails.Id, "User");
                }
            }


            if (result.Succeeded)
            {
                //await SignInManager.SignInAsync(userDetails, isPersistent:false, rememberBrowser:false);
                // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
                // Send an email with this link
                // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href='"" + callbackUrl + "'">here</a>");
                //return RedirectToAction("Index", "Home");
                return Json("Password sent!");
            }
            AddErrors(result);
        }
        // If we got this far, something failed, redisplay form
        //return View(model);
        return View();
    }

这是我的视图:

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form", id = "registrationForm" }))
    {
    @Html.AntiForgeryToken()

    @Html.ValidationSummary("", new { @class = "text-danger" })
    <div class="form-group">
        <div class="col-md-2">
            <select class="form-control" id="Title" name="Title">
                <option value="M." selected>title</option>
                <option value="Mr.">Mr.</option>
                <option value="Ms.">Ms.</option>
                <option value="Mrs.">Mrs.</option>
                <option value="M.">M.</option>
                <option value="—————————————" disabled>—————————————</option>
                <option value="Dr.">Dr.</option>
                <option value="Rev.">Rev.</option>
            </select>
        </div>
        <div class="col-md-3">
            @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control", @placeholder = "first name" })
        </div>
        <div class="col-md-3">
            @Html.TextBoxFor(m => m.LastName, new { @class = "form-control", @placeholder = "last name" })
        </div>
        <div class="col-md-4" style="font-size:24px; text-align:center; color:#3D3D3D;">
            name &amp; email
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-4">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @placeholder = "email" })
        </div>
        <div class="col-md-4">
            @Html.TextBoxFor(m => m.PhoneNumber, new { @class = "form-control", @placeholder = "phone" })
        </div>
        @Html.HiddenFor(m => m.Id, new { Value = "-9999" })

    </div>
    <div class="form-group">
        <div class="col-md-4">
            @Html.CheckBoxFor(m => m.IsAccountActive)
            &nbsp;
            @Html.LabelFor(m => m.IsAccountActive, new { @class = "control-label" })
        </div>
        <div class="col-md-8">
            &nbsp;
        </div>
    </div>
    <hr style="padding-top:0;" />
    <div id="passwordOptions" style="display:none;">
        <div class="form-group">
            <div class="col-md-4">
                For security reasons, passwords cannot be viewed or edited manually.
            </div>
            <div class="col-md-4">
                <a href="#" id="resetPasswordButton" class="btn btn-primary btn-block disabled">reset/email password</a>
            </div>
            <div class="col-md-4" style="font-size:24px; text-align:center; color:#3D3D3D;">
                password
            </div>
        </div>
        <hr />
    </div>

    <div class="form-group">
        @if(User.IsInRole("SuperAdmin"))
        {
        <div class="col-md-8" id="districtSelectButtonArea">
            <button type="button" id="selectDistrictButton" class="btn btn-success col-sm-12"><span class="glyphicon glyphicon-briefcase"></span>&nbsp;select lea/district</button>
        </div>
        <div class="col-md-8" id="districtSelectionArea" style="display:none;">
            <div class="col-md-2">&nbsp;</div>
        </div>
        }

        @if(User.IsInRole("SchoolAdmin"))
        {
        <div class="col-md-8" id="blankSpot">&nbsp;</div>
        }
        <div class="col-md-4" style="font-size:24px; text-align:center; color:#3D3D3D;">
            charter school info
        </div>
    </div>
        if (User.IsInRole("LEAAdmin") || User.IsInRole("SuperAdmin"))
        {
            <div class="form-group">
                <div class="col-md-2" id="makeLEAAdminArea">
                    @Html.CheckBoxFor(m => m.LEAAdmin)
                    @Html.LabelFor(m => m.LEAAdmin, new { @class = "control-label" })
                </div>
                <div class="col-md-3" id="backgroundOnFileArea">
                    @Html.CheckBoxFor(m => m.BackgroundOnFile)
                    @Html.LabelFor(m => m.BackgroundOnFile, new { @class = "control-label" })
                </div>
            </div>

        }
    <div class="form-group">
        <div class="col-md-2">
            @Html.CheckBoxFor(m => m.IsBoardMember)
            @Html.LabelFor(m => m.IsBoardMember, new { @class = "control-label" })
        </div>
        <div class="col-md-2">
            @Html.CheckBoxFor(m => m.IsBoardChair)
            @Html.LabelFor(m => m.IsBoardChair, new { @class = "control-label" })
        </div>
     </div>
    <div class="form-group">
@if(User.IsInRole("SuperAdmin"))
            {
        <div class="col-md-12 bg-warning" style="margin-bottom:5px;">The following applies to Board users <strong>only</strong></div>
                <div class="col-md-4">
                    @Html.TextBoxFor(m => m.BoardStart, new { @class = "form-control", @placeholder = "charter board start date" })
                </div>
                <div class="col-md-4">
                    @Html.TextBoxFor(m => m.BoardEnd, new { @class = "form-control", @placeholder = "charter board end date" })
                </div>
        <div class="col-md-4">
            <select id="NominatedBy" class="form-control" name="NominatedBy">
                <option value="">nominated to school board by</option>
                <option value="financeSB">finance &amp; small business</option>
                <option value="cs">charter schools</option>
                <option value="Super">state board of education</option>
            </select>
            </div>
        }

    </div>
    if(User.IsInRole("SuperAdmin"))
    {
    <div id="permissionsArea" style="display:none;">
        <hr />
        create and manage <strong>system</strong> administrators<br /><br />
        <div class="form-group">
            <div class="col-md-2">
                <button type="button" id="makeFullAdminButton" class="btn btn-default"><span class="glyphicon glyphicon-circle-arrow-up"></span> make full admin</button>
            </div>
            <div class="col-md-3">
                <button type="button" id="removeAdminButton" class="btn btn-danger"><span class="glyphicon glyphicon-circle-arrow-down"></span> remove admin access</button>
            </div>
            <div class="col-md-3">
                <button type="button" id="removeAdminButton" class="btn btn-success"><span class="glyphicon glyphicon-minus"></span> make read-only admin</button>
            </div>
            <div class="col-md-4" style="font-size:24px; text-align:center; color:#3D3D3D;">
                permissions
            </div>
        </div>
    </div>
    }

    <div class="form-group" id="regButtonArea" style="display:none;">
        <div class="col-md-4 col-md-offset-2">
            <button type="submit" id="registerButton" class="btn btn-primary col-md-12"><span class="glyphicon glyphicon-pencil"></span> register for UCAP</button>
        </div>
        <div class="col-md-4">any passwords, if applicable, will be emailed to the user</div>
    </div>
    }

这是ViewModel:公共类RegisterViewModel{

    [Display(Name = "Title")]
    public string Title { get; set; }
    [Required(ErrorMessage = "First Name is required")]
    [Display(Name = "First Name")]
    public string FirstName { get; set; }
    [Required(ErrorMessage = "Last Name is required")]
    [Display(Name = "First Name")]
    public string LastName { get; set; }
    [Required]
    [HiddenInput]
    public int LEAID { get; set; }
    [Required]
    [HiddenInput]
    public int SchoolID { get; set; }
    [HiddenInput]
    public string Id { get; set; }
    [Required]
    [Display(Name="Account Active?")]
    public bool IsAccountActive { get; set; }
    [Required(ErrorMessage = "Email address is required")]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    //Address functionality disabled but not removed for possible future use
    /*
    [Required(ErrorMessage = "Address is required")]
    [Display(Name = "Address Line 1")]
    public string Address1 { get; set; }
    [Display(Name = "Address Line 2")]
    public string Address2 { get; set; }
    [Required(ErrorMessage = "City is required")]
    [Display(Name = "City")]
    public string City { get; set; }
    [Required(ErrorMessage = "State")]
    [Display(Name = "State")]
    [MinLength(2)]
    public string State { get; set; }
    [Required(ErrorMessage = "Postal Code is required")]
    [Display(Name = "Postal Code")]
    public string PostCode { get; set; }
    */
    [Display(Name = "LEA Admin")]
    public bool LEAAdmin { get; set; }
    [Required(ErrorMessage = "Phone Number")]
    [Display(Name = "Phone")]
    public string PhoneNumber { get; set; }
    [Display(Name = "Background Check on File")]
    public bool BackgroundOnFile { get; set; }
    //Dates have to be set to nullable or the model binder will force them as required
    [Display(Name = "Board Start Date")]
    public System.Nullable<System.DateTime> BoardStart { get; set; }
    [Display(Name = "Board End Date")]
    public System.Nullable<System.DateTime> BoardEnd { get; set; }
    [Display(Name = "Nominated By")]
    public string NominatedBy { get; set; }
    [Display(Name = "Board Chair")]
    public bool IsBoardChair { get; set; }
    [Display(Name = "Board Member")]
    public bool IsBoardMember { get; set; }
    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }
    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [System.Web.Mvc.CompareAttribute("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

当测试视图时,我去到AccountController中的Login方法,而不是Register。Login是控制器中的第一个方法。

 [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, change to shouldLockout: true
        var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe = false, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                    return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl});
            case SignInStatus.Failure:
                ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
            default:
                ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
        }
    }

MVC控制器和身份2.1 -从注册方法意外跳转到登录方法

我的问题是错误地写出了授权属性。在我这边的实验中,我添加了第二个角色,我没有把它写成[Authorize(Roles="SuperAdmin, Admin")]。错误地设置了两个单独的属性:

[Authorize(Roles="SuperAdmin")]
[Authorize(Roles="Admin")]

修复这个修复了这个问题!