Frage

Ich schreibe eine ASP.NET MVC 2.0-Anwendung, die Benutzer anmelden müssen, bevor ein Gebot auf einen Artikel platzieren. Ich verwende einen Actionfilter, um sicherzustellen, dass der Benutzer in und angemeldet ist, wenn nicht, um sie zu einer Login-Seite senden und die Rückkehr url gesetzt. Unten ist der Code, den ich in meinem Action-Filter verwendet werden.

if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
    filterContext.Result = new RedirectResult(String.Concat("~/Account/LogOn","?ReturnUrl=",filterContext.HttpContext.Request.RawUrl));
    return;
}

In meinem Anmelde Controller ich die Benutzer-Anmeldeinformationen validieren dann unterschreibt sie in und Umleitung auf die Rückkehr url

FormsAuth.SignIn(userName, rememberMe);
if (!String.IsNullOrEmpty(returnUrl))
{
    return Redirect(returnUrl);
}

Mein Problem ist, dass dies immer ein Get (HttpGet) Anfrage verwenden wird während meiner ursprünglichen Vorlage ein Post (Httppost) war und sollte immer ein Beitrag sein. Kann jemand empfehlen, eine Möglichkeit, diese URL vorbei einschließlich der Httpmethod oder eine Abhilfe, um sicherzustellen, dass die richtige Httpmethod verwendet wird?

War es hilfreich?

Lösung

Es gibt keinen einfachen Weg, dies zu tun. Was würde ich Ihnen empfehlen, ist die nicht-autorisierte Benutzer auf die Anmeldeseite nicht beim Verfassen eines Beitrags zu einem gewissen URL umleiten, aber wenn Ihr Interesse an der Form, das wird POST an den authentifizierten URL.

Wenn Sie wissen, dass das Formular, das Sie auf einen nicht authentifizierter Benutzer präsentieren zu einem authentifizierten Teil der Website POST wird, na ja, präsentiere ihn nicht die Form. Wenn diese Form angefordert wird einfach auf die Anmeldeseite für die Authentifizierung umleiten und einmal authentifizierten Umleitung auf die ursprüngliche Form zurück. Auf diese Weise werden Sie sicherstellen, dass nur authentifizierte Benutzer auf die geschützte Ressource POST wird.

Soweit automatisierte POST-Anforderungen betroffen sind (Bots, Web-Service, ...) einen einfachen Statuscode 401 auf Anfragen der Rückkehr, die Anmeldeinformationen nicht zur Verfügung stellen sollen mehr als ausreichend.

Andere Tipps

Ich glaube, ich bekommen, warum Sie die Authentifizierung nur auf der Bid POST Aktion. Ein Gebot erfordert Login, aber jeder nicht-angemeldeter Benutzer kann die Auktion Seite. Genau wie ebay / amazon etc. Alles ist sichtbar, bis Sie die Zahlung oder eine Aktion auf der Grundlage eines Benutzers erforderlich ist.

Sie könnten Ihr Attribut ändern, anstatt die Request.UrlReferrer auf die Login-Seite zurückzukehren, wenn die Request.RequestType ein POST ist. Dann würden sie auf der Auktionsseite umgeleitet werden und können wieder Gebot klicken, sobald sie angemeldet sind. Sie selbst entlang einer bestimmten Feld passieren könnte, sagen Menge, mit der UrlReferrer so dass Sie die Menge Feld wieder auffüllen konnte, sobald sie auf dem Land Auktionsseite. Sie könnten das Feld aus der Request.Form Sammlung erhalten.

// in usage...    
[RequireLogin(AdditionalFields="amount,someotherfield")]
[HttpPost]
public ActionResult Bid(.....)

// the attribute 
class RequireLoginAttribute : ActionFilterAttribute
{
    public string AdditionalFields { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            var returnUrl = filterContext.HttpContext.Request.RawUrl;
            if (filterContext.HttpContext.Request.RequestType == "POST")
            {
                returnUrl = filterContext.HttpContext.Request.UrlReferrer.PathAndQuery;
                // look for FORM values in request to append to the returnUrl
                // this can be helpful for a good user experience (remembering checkboxes/text fields etc)
            }

            filterContext.Result = new RedirectResult(String.Concat("~/Account/LogOn", "?ReturnUrl=", returnUrl));
            return;
        }
        base.OnActionExecuting(filterContext);
    }
}

Sie können mit dem gleichen Namen zwei Controller-Methoden schreiben, aber einen für get und eine andere für die Post, und erinnern dich an die ReturnUrl in der get-Methode in TempData (oder Sitzung), und dann die ReturnUrl von TempData erhalten, wenn Post-Anforderung ankommt:

Der Code kann wie folgt aussieht:

    public ActionResult LogOn(string returnUrl)
    {
        if (!string.IsNullOrEmpty(returnUrl))
        {
            TempData["ReturnUrl"] = returnUrl;
        }
        return View();
    }

    [HttpPost]
    public ActionResult LogOn(LogOnModel model, FormCollection collecton)
    {
        if (ModelState.IsValid)
        {
            AuthenticationResult logonStatus = TransactionScriptFactory.GetTransactionScript<UserTransactionScripts>()
                                                                       .LogOn(model.Email, model.Password);

            if (logonStatus.AuthResult == AuthResultEnum.Success)
            {
                FormsService.SignIn(logonStatus.User.UserId, logonStatus.User.NickName, false);

                object returnUrl = string.Empty;
                TempData.TryGetValue("ReturnUrl", out returnUrl);
                string returnUrlStr = returnUrl as string;
                if (!string.IsNullOrEmpty(returnUrlStr))
                {
                    return Redirect(returnUrlStr);
                }
                else
                {
                    return RedirectToAction("Index", "Home");
                }
            }

......

Es ist auf jeden Fall, wenn Sie zuerst auf die Seite kommt von get Aktion verwenden, dann post-Daten an den Server.

Ich glaube, Sie auch die ganze URL aus Request.UrlReferrer erhalten können.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top