重定向到returnURL不起作用 [英] Redirect to returnURL not working

查看:108
本文介绍了重定向到returnURL不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

参考此发布的问题

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

The answer given does not work for me and I am having the same problem here.

我也在使用aspnet身份验证,用户可以尝试导航到站点上的任何页面,特别是对于用户来说,导航到/mycontroller/myaction/25之类的东西非常普遍,其中25是帐户或产品该用户经常使用的标识符.

I'm also using aspnet authentication and a user can try to navigate to any page on the site, specifically it is very common for a user to navigate to something like /mycontroller/myaction/25 where 25 is an account or product identifier that is used very often by that user.

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

If the user is currently not authenticated when trying to access that url, they are redirected to the logon screen. After logon, the redirect(returnURL) is NOT navigating the user to the requested page. The page stays on the login screen.

用户在登录之前粘贴到地址栏中的URL可以是:

The url that a user would paste into the address bar before login could be:

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

输入凭据并进行调试以查看凭据已通过身份验证后,URL相同

After entering credentials and debugging to see that the credentials were authenticated, the URL is the same

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

股票mvc项目与我的mvc项目之间的区别在于,我要做的不仅仅是登录操作时发生的登录.这是我的代码:(显然,通过减小每个函数的体积来破坏某些东西)

The difference between the stock mvc project and mine is that I have a little more than just a logon happening at the login action. Here is my code: (I've obviously broken something by making each function small and contained)

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检查处于同一操作中,但仍然不起作用:

I tried changing the Post action so that the returnURL check is in the same action but it still doesn't work:

    [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将我的代码改回我最初使用的方式,它可以完美地工作...因此,这告诉我,它与我正在执行的操作的顺序有关,而不是其他任何事情...将尝试重新对较小的方法进行排序以匹配此操作的顺序并查看会发生什么情况

Update 2 Changing my code back to the way I orginally had it, it works perfect... so this tells me that it has more to do with the ordering of the what I'm doing than anything else... going to try to re-order the smaller methods to match the order of this action and see what happens

    [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

此问题已解决,请自行解决:-)

This fixed it, got it on my own :-)

    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");
        }
    }

推荐答案

解决方法是将cookie设置得比以前更早.仅当我调用了正在设置cookie的ForwardUserToHomePage方法时,才设置cookie,然后将其重定向到home/index.但是由于该方法从未被调用,因为我正在执行redirect(returnUrl),并且未设置cookie.由于未设置该重定向,因此重定向失败,因为客户端认为该用户以前尚未登录,因此实际上是登录页面被再次击中".

The fix was to set the cookie earlier than I was before. I was setting the cookie only when I called ForwardUserToHomePage method where the cookie was being set and then redirect to home/index. But since that method was never being called as I was doing a redirect(returnUrl) instead and the cookie wasn't set. Since it wasn't set, the redirect failed as the client believed the used to not yet be logged in, hence the login page was "being hit again" in actuality.

将我的AuthenticateCredentials方法修改为:

Modified my AuthenticateCredentials method to be:

    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");
        }
    }

这篇关于重定向到returnURL不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆