重定向到returnURL不起作用

时间:2012-05-03 12:07:16

标签: asp.net-mvc-3

参考this posted question

给出的答案对我不起作用,我在这里遇到同样的问题。

我也在使用aspnet身份验证,用户可以尝试导航到网站上的任何页面,特别是用户导航到/ mycontroller / myaction / 25这样的地方很常见,其中25是帐户或产品该用户经常使用的标识符。

如果用户在尝试访问该URL时当前未经过身份验证,则会将其重定向到登录屏幕。登录后,重定向(returnURL)不会将用户导航到请求的页面。该页面保留在登录屏幕上。

用户在登录前粘贴到地址栏中的网址可能是:

http://localhost:4082/Account/LogOn?ReturnUrl=%2fProduct%2fEdit%2f59

输入凭据并进行调试以查看凭据是否经过身份验证后,URL是相同的

http://localhost:4082/Account/LogOn?ReturnUrl=%2fProduct%2fEdit%2f59

股票mvc项目和我的项目之间的区别在于,我只需要在登录操作中进行登录。这是我的代码:(我显然已经通过使每个函数变小并包含来破坏了某些东西)

public ActionResult LogOn() {
    if (User.Identity.IsAuthenticated)
        return RedirectToAction("Index", "Home");
    var model = new LogOnViewModel();
    return View(model);
}

[HttpPost]
public ActionResult LogOn(LogOnViewModel model, string returnUrl) {
    if (ModelState.IsValid) {
        try {
            return AttemptToAuthenticateUser(model, returnUrl);
        }
        catch (Exception ex) {
            ModelState.AddModelError("", ex.Message);
        }
    }
    return View(model);
}

private ActionResult AttemptToAuthenticateUser(LogOnViewModel model, string returnUrl) {
    var membershipUser = GetUserFromMembershipProvider(model.Username, false);
    var audit = new LoginAudit(model.Username, model.Password, Request.Browser.Browser, Request.Browser.Type, Request.UserHostAddress);
    VerifyUserAccountIsApprovedNotLockedOut(membershipUser);
    AuthenticateCredentials(model, audit);
    AuditLogon(audit, model.Username, true);
    return ForwardToLogonResultAction(membershipUser, returnUrl, model.RememberMe);
}

internal static MembershipUser GetUserFromMembershipProvider(string username, bool isUserCurrentlyLoggedIn) {
    var membershipUser = Membership.GetUser(username, isUserCurrentlyLoggedIn);
    if (membershipUser == null)
        throw new Exception("The user account was not found");
    return membershipUser;
}

internal static void VerifyUserAccountIsApprovedNotLockedOut(MembershipUser membershipUser) {
    if (membershipUser.IsLockedOut || !membershipUser.IsApproved)
        throw new Exception("This account has been disabled or has been locked out. Please contact Administration for support");
}

private void AuthenticateCredentials(LogOnViewModel model, LoginAudit audit) {
    if (Membership.ValidateUser(model.Username, model.Password)) { }
    else {
        AuditLogon(audit, model.Username, false);
        throw new Exception("The user name or password provided is incorrect");
    }
}

private void AuditLogon(LoginAudit audit, string username, bool isSuccessfullyAuthenticated) {
    if (isSuccessfullyAuthenticated)
        audit.Password = string.Empty;
    audit.Save(username);
}

private ActionResult ForwardToLogonResultAction(MembershipUser currentMembershipUser, string returnUrl, bool rememberMe) {
    if (IsPasswordOnAccountTemporary((Guid)currentMembershipUser.ProviderUserKey))
        return RedirectToAction("Edit", "ChangePassword");
    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) {
        return Redirect(returnUrl);
    }
    return ForwardUserToHomePage(currentMembershipUser.UserName, rememberMe);
}

private bool IsPasswordOnAccountTemporary(Guid userGUID) {
    var profile = new Profile(userGUID);
    return profile.IsTemporaryPassword;
}

更新

我尝试更改Post操作,以便returnURL检查处于同一操作但仍然无效:

    [HttpPost]
    public ActionResult LogOn(LogOnViewModel model, string returnUrl) {
        if (ModelState.IsValid) {
            try {
                AttemptToAuthenticateUser(model, returnUrl);
                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) 
                    return Redirect(returnUrl);
                return ForwardUserToHomePage(model.Username, model.RememberMe);
            }
            catch (Exception ex) {
                ModelState.AddModelError("", ex.Message);
            }
        }
        return View(model);
    }

更新2 改变我的代码回到我原来的方式,它完美地工作......所以这告诉我它更多地与我正在做的事情的排序比其他任何东西一样...试图重新命令较小的方法来匹配此操作的顺序,看看会发生什么

    [HttpPost]
    public ActionResult LogOn(LogOnViewModel model, string returnUrl) {
        if (ModelState.IsValid) {
            MembershipUser currentUser;
            var audit = new LoginAudit(model.Username, model.Password, Request.Browser.Browser, Request.Browser.Type, Request.UserHostAddress);
            if (Membership.ValidateUser(model.Username, model.Password)) {
                audit.Password = string.Empty;
                FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
                currentUser = Membership.GetUser(model.Username, true);
                if (currentUser != null && currentUser.ProviderUserKey != null) {
                    var profile = new Profile((Guid)currentUser.ProviderUserKey);
                    if (profile.IsTemporaryPassword)
                        return RedirectToAction("Edit", "ChangePassword");
                }
                if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\")) {
                    return Redirect(returnUrl);
                }
                return RedirectToAction("Index", "Home");
            }
            currentUser = Membership.GetUser(model.Username, false);
            if (currentUser != null && (currentUser.IsLockedOut || !currentUser.IsApproved)) {
                ModelState.AddModelError("", "This account has been locked out. Please contact ELM Administration for support.");
            }
            else {
                ModelState.AddModelError("", "The user name or password provided is incorrect.");
            }
            audit.Save(model.Username);
        }
        return View(model);
    }

Udpate 3

这解决了它,我自己得到它: - )

    private void AuthenticateCredentials(LogOnViewModel model, LoginAudit audit) {
        if (Membership.ValidateUser(model.Username, model.Password)) {
            FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
        }
        else {
            AuditLogon(audit, model.Username, false);
            throw new Exception("The user name or password provided is incorrect");
        }
    }

2 个答案:

答案 0 :(得分:7)

Logon视图中,您是否将网址传递给HttpPost方法?

 @using (Html.BeginForm("LogOn", "Account", new { returnUrl= Request.QueryString["ReturnUrl"] }))
 {
     //your form elements
   <input type="submit" value="Login" />
 }

答案 1 :(得分:-1)

修复是比以前更早地设置cookie。我只是在调用正在设置cookie的ForwardUserToHomePage方法然后重定向到home / index时才设置cookie。但是因为我从未调用该方法,因为我正在进行重定向(returnUrl)而没有设置cookie。由于没有设置,重定向失败,因为客户端认为用户还没有登录,因此登录页面实际上是“再次被击中”。

将我的AuthenticateCredentials方法修改为:

    private void AuthenticateCredentials(LogOnViewModel model, LoginAudit audit) {
        if (Membership.ValidateUser(model.Username, model.Password)) {
            FormsAuthentication.SetAuthCookie(model.Username, model.RememberMe);
        }
        else {
            AuditLogon(audit, model.Username, false);
            throw new Exception("The user name or password provided is incorrect");
        }
    }