1

この投稿された質問を参照して

与えられた答えは私にはうまくいきません。ここで同じ問題を抱えています。

私は aspnet 認証も使用しており、ユーザーはサイトの任意のページに移動しようとすることができます。具体的には、ユーザーが /mycontroller/myaction/25 のような場所に移動することは非常に一般的です。ここで、25 はアカウントまたは製品 ID です。そのユーザーによって非常に頻繁に使用されます。

その URL にアクセスしようとしたときにユーザーが現在認証されていない場合、ユーザーはログオン画面にリダイレクトされます。ログオン後、リダイレクト (returnURL) はユーザーを要求されたページに移動しません。ページはログイン画面にとどまります。

ユーザーがログイン前にアドレス バーに貼り付ける URL は次のようになります。

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

アップデート

returnURL チェックが同じアクションになるように Post アクションを変更しようとしましたが、それでも機能しません。

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

アップデート 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");
        }
    }
4

2 に答える 2

7

ビューで、url を HttpPost メソッドに渡していますLogonか?

 @using (Html.BeginForm("LogOn", "Account", new { returnUrl= Request.QueryString["ReturnUrl"] }))
 {
     //your form elements
   <input type="submit" value="Login" />
 }
于 2012-05-03T12:43:13.867 に答える
0

修正は、以前よりも早く Cookie を設定することでした。Cookieが設定されているForwardUserToHomePageメソッドを呼び出してからホーム/インデックスにリダイレクトしたときにのみ、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");
        }
    }
于 2012-05-03T13:19:35.210 に答える