Question

Je suis en train d'écrire une application ASP.NET MVC 2.0 oblige les utilisateurs à se connecter avant de placer une enchère sur un objet. J'utilise un ActionFilter pour faire en sorte que l'utilisateur est connecté et, sinon, de les envoyer à une page de connexion et définir l'URL de retour. Voici le code que j'utilise dans mon filtre d'action.

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

Dans mon contrôleur d'ouverture de session, je valide les utilisateurs des informations d'identification signer ensuite et redirection vers l'URL retour

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

Mon problème est que ce sera toujours utiliser un Get (HttpGet) demande alors que ma demande initiale était un poste (HttpPost) et doit toujours être un poste. Quelqu'un peut-il suggérer une façon de passer cette URL, y compris la HttpMethod ou toute solution pour assurer que le bon HttpMethod est utilisé?

Était-ce utile?

La solution

Il n'y a pas de moyen facile de le faire. Ce que je vous recommande est de rediriger les utilisateurs non authentifiés à la page de connexion non lors de la publication à une URL, mais lorsque vous demandez le formulaire qui POST à ??l'URL authentifiées.

Si vous savez que le formulaire que vous présentez à un utilisateur non authentifié sera POST à ??une partie authentifiée du site, eh bien, ne se présente pas sous la forme. Lorsque ce formulaire est demandé simplement rediriger vers la page de connexion pour l'authentification et une redirection authentifiées à la forme originale. De cette façon, vous vous assurerez que seuls les utilisateurs authentifiés afficherons à la ressource protégée.

En ce qui concerne les requêtes POST automatiques sont concernés (robots, services web, ...) retour d'un simple code d'état 401 aux demandes qui ne fournissent pas des informations d'identification devraient être plus que suffisant.

Autres conseils

Je pense que je reçois pourquoi vous voulez que l'authentification soit uniquement sur l'offre de l'action POST. Une offre nécessite une connexion, mais une non-utilisateur connecté peut voir la page d'enchères. Tout comme ebay / amazon etc Tout est visible jusqu'à ce que vous avez besoin de paiement ou une action en fonction d'un utilisateur.

Vous pouvez changer votre attribut pour revenir à la place du Request.UrlReferrer à la page de connexion si le Request.RequestType est un POST. Ensuite, ils seront redirigés vers la page d'enchères et peuvent cliquer sur une offre à nouveau une fois qu'ils sont connectés. Vous pouvez même passer le long d'un certain domaine, disons montant, avec le UrlReferrer afin que vous puissiez repeupler le champ du montant une fois qu'ils atterrissent sur la page d'enchères. Vous pouvez obtenir ce champ de la collection Request.Form.

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

Vous pouvez écrire deux méthodes contrôleur avec le même nom, mais un pour get et un autre post, et rappelez-vous le ReturnUrl dans la méthode get dans TempData (ou session), puis obtenir le ReturnUrl de TempData lorsque la demande après l'arrivée:

Le code peut ressembler à ceci:

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

......

Il est sans aucun doute lorsque vous arrivez à la page en utilisant l'action get, puis les données post sur le serveur.

Je pense que vous pouvez également obtenir toute URL de Request.UrlReferrer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top