Pregunta

Estoy escribiendo una aplicación ASP.NET MVC 2.0, que requiere que los usuarios iniciar sesión antes de hacer una oferta en un artículo. Estoy utilizando un actionfilter para asegurar que el usuario está conectado y, si no, los envían a una página de registro y establecer la dirección URL de retorno. A continuación se muestra el código que utilizo en mi filtro de acción.

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

En mi inicio de sesión de controlador de E validar las credenciales de los usuarios a continuación, firmar y redirección a la URL de devolución

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

Mi problema es que esto siempre va a utilizar una solicitud GET (HttpGet) mientras que mi presentación original era un puesto (HttpPost) y siempre debe ser un poste. ¿Puede alguien sugerir una manera de pasar este URL incluyendo el HTTPMethod o cualquier solución para asegurar que la correcta HTTPMethod se utiliza?

¿Fue útil?

Solución

No hay manera fácil de hacer esto. Lo que yo recomendaría que es redirigir a los usuarios no autenticados a la página de inicio de sesión no cuando anuncio a alguna URL, pero al momento de solicitar el formulario que se acreditarán en la URL autenticado.

Si sabe que la forma va a presentar a un usuario no autenticado a publicar a una parte auténtica de su sitio, así, no presentan la forma de él. Cuando se solicita esta forma simplemente redirigir a la página de inicio de sesión para la autenticación y una vez autenticado redirección a la forma original. De esta manera se asegurará de que sólo los usuarios autenticados se publique en el recurso protegido.

En lo que se refiere a las solicitudes POST automatizados (robots, servicios web, ...) que devuelve un código de estado 401 sencilla a las solicitudes que no proporcionan credenciales deben ser más que suficiente.

Otros consejos

Creo que entiendo por qué desea que la autenticación sea sólo en la acción POST oferta. Una oferta requiere inicio de sesión, pero cualquier no-conectados puede ver la página de la subasta. Al igual que eBay / Amazon, etc. Todo es visible hasta que exigen el pago o acción basado en un usuario.

Se podría cambiar su atributo para volver al lugar Request.UrlReferrer a la página de inicio de sesión si el Request.RequestType es un POST. Entonces ellos serán redireccionados a la página de la subasta y pueden hacer clic en pujar de nuevo una vez que se registran en. Incluso se puede pasar a lo largo de un determinado campo, por ejemplo cantidad, con el UrlReferrer por lo que podría volver a poblar el campo de cantidad, una vez que la tierra en el página de la subasta. Se podría conseguir que el campo de la colección 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);
    }
}

Puede escribir dos métodos de controlador con el mismo nombre, pero uno para get y otra para el poste, y recordar el ReturnUrl en el método get en TempData (o sesión), y luego obtener el ReturnUrl de TempData cuando solicitud POST llega:

El código puede es similar al siguiente:

    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 definitivamente la primera vez que llega a la página mediante la acción GET, a continuación, después de servidor.

Creo que también se puede obtener toda la url de Request.UrlReferrer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top