Вопрос

Я пишу приложение ASP.NET MVC 2.0, которое требует от пользователей, прежде чем разместить ставку на элемент. Я использую ActionFilter, чтобы убедиться, что пользователь вошел в систему, и, если нет, отправьте их на страницу входа и установите возвратный URL. Ниже приведен код, который я использую в моем фильтре действий.

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

В моем контроллере входа в систему я проверяет учетные данные пользователя, затем подпишите их и перенаправляйте на возвратный URL

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

Моя проблема в том, что это всегда будет использовать запрос Get (httpget), тогда как мое первоначальное представление было пост (httpPost) и всегда должен быть постом. Может кто-нибудь предложить способ передачи этого URL, включая httpmethod или любой обходной путь, чтобы гарантировать, что правильный httpmethod используется?

Это было полезно?

Решение

Там нет простого способа сделать это. То, что я бы порекомендовал вам, чтобы перенаправить неавтоматические пользователи на странице входа в систему, не при публикации к некоторому URL, но при запросе формы, которая будет опубликовать до аутентифицированного URL.

Если вы знаете, что форма, которую вы представляете на ненушительный пользователь, опубликуют на аутентифицированную часть сайта, ну, не представляйте ему форму. Когда эта форма запрашивается просто перенаправить на страницу входа в систему для аутентификации и после того, как аутентифицированные перенаправляются в исходную форму. Таким образом, вы убедитесь, что только аутентифицированные пользователи будут публиковать на защищенный ресурс.

Что касается автоматической почты запросов (боты, веб-сервисы, ...) возвращают простой код состояния 401 для запросов, которые не предоставляют учетные данные, должны быть более чем достаточными.

Другие советы

Я думаю, что я получаю, почему вы хотите, чтобы аутентификация была только в ставке POST действие. Ставка требует входа в систему, но любой не зарегистрированный пользователь, может увидеть страницу аукциона. Так же, как eBay / Amazon и т. Д. Все видно, пока вам не требуется оплата или действие на основе пользователя.

Вы можете изменить свой атрибут вместо этого возвращать Request.UrlReferrer на страницу входа в систему, если Request.RequestType это POST. Отказ Затем они будут перенаправлены на страницу аукционов и можете снова нажимать ставку, как только они вошли в систему. Вы могли бы даже пройти по определенной области, скажем, сумма, с UrlReferrer Так что вы могли бы повторно заполнить полевое поле, когда они приземляются на странице аукциона. Вы можете получить эту поле из 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);
    }
}

Вы можете написать два метода контроллера с тем же именем, но один для получения и другого для поста и запомнить returnUrl в методе Get в Tempdata (или сеансе), а затем получить возврат от Tempdata, когда поступил почтовый запрос:

Код может выглядеть так:

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

......

Это неопределенно, когда вы сначала поставляетесь на страницу, используя Get Action, затем опубликовать данные на сервер.

Я думаю, что вы также можете получить весь URL-адрес Request.urlreferrer.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top