如果用户将表单提交到仅POST操作并且其身份验证已超时,则登录后重定向会导致404错误

stu*_*win 5 asp.net-mvc forms-authentication http-post

我有一个使用表单身份验证的MVC应用程序,我收到404错误.发生的事情是,当用户的身份验证超时时,用户恰好将表单提交给仅POST操作,并将其重定向到登录页面.登录后,他们将使用GET重定向回原始URL,这将导致404错误,因为操作仅限POST.

我有两个问题:

  1. 解决这个问题的想法是以某种方式检测被重定向到的动作是否是仅POST操作,而是重定向到主页.我该怎么做呢?

  2. 理想情况下,应用程序会记住发布的值,并通过POST将它们提交到原始URL,但我不知道如何绕过Forms身份验证来执行此操作,我怀疑这会对安全漏洞开放.这是一个好主意,如果是这样,怎么办呢?

stu*_*win 3

根据上面的回复,我创建了一个操作过滤器,我将把它留在这里供后代使用。它将所有指定的参数从尝试的操作传递到重定向操作。

public class HttpPostOrRedirectAttribute : ActionFilterAttribute
{
    public string RedirectAction { get; set; }
    public string RedirectController { get; set; }
    public string[] ParametersToPassWithRedirect { get; set; }

    public HttpPostOrRedirectAttribute(string redirectAction)
        : this(redirectAction, null, new string[] { })
    {
    }

    public HttpPostOrRedirectAttribute(string redirectAction, string[] parametersToPassWithRedirect)
        : this(redirectAction, null, parametersToPassWithRedirect)
    {
    }

    public HttpPostOrRedirectAttribute(string redirectAction, string redirectController, string[] parametersToPassWithRedirect)
    {
        RedirectAction = redirectAction;
        RedirectController = redirectController;
        ParametersToPassWithRedirect = parametersToPassWithRedirect;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.HttpMethod == "POST")
        {
            base.OnActionExecuting(filterContext);
        }
        else
        {
            string redirectUrl = GetRedirectUrl(filterContext.RequestContext);
            filterContext.Controller.TempData["Warning"] = "Your action could not be completed as your"
                + " session had expired.  Please try again."; 
            filterContext.Result = new RedirectResult(redirectUrl);               
        }
    }

    public string GetRedirectUrl(RequestContext context)
    {
        RouteValueDictionary routeValues = new RouteValueDictionary();
        foreach (string parameter in ParametersToPassWithRedirect)
        {
            if(context.RouteData.Values.ContainsKey(parameter))
                routeValues.Add(parameter, context.RouteData.Values[parameter]);
        }
        string controller = RedirectController 
            ?? context.RouteData.Values["controller"].ToString();
        UrlHelper urlHelper = new UrlHelper(context);
        return urlHelper.Action(RedirectAction, controller, routeValues);           
    }
}
Run Code Online (Sandbox Code Playgroud)

使用时,只需将HttpPost相关操作上的过滤器替换为HttpPostOrRedirect

[HttpPostOrRedirect("Display", "User", new[] { "id", "param1", "param2" })]
public ActionResult Delete(User user, int param1, string param2)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)