Подтвердить что ты не робот

Пользовательский механизм Asp.net Mvc для обработки несанкционированного запроса

Для моего сайта я хочу следующее поведение для защищенного контроллера (или действия)

если пользователь перенаправляет обычный запрос на страницу входа (что я легко могу сделать)

если запрос - это тип Ajax Request.IsAjaxRequest()==true, код статуса возврата 401

Как я могу создать фильтр для этого?

4b9b3361

Ответ 1

 public class MyCustomAuthorize : AuthorizeAttribute
{
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            //if ajax request set status code and end Response
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                filterContext.HttpContext.Response.StatusCode = 401;
                filterContext.HttpContext.Response.End();
            }

            base.HandleUnauthorizedRequest(filterContext);
        }
}

Создайте фильтр, как указано выше, он вернет код состояния 401 для несанкционированного запроса, если запрос сделан через ajax.

Если вы используете jQuery, вы можете сделать это ниже

jQuery.ajax({
statusCode: {
    401: function() {
      alert('unauthrized');
    },

  /*other options*/
});

Ответ 2

В дополнение к принятому ответу мне нужно было вставить эту строку кода, чтобы предотвратить переадресацию FormsAuthentication на страницу входа.

filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;

Затем я удалил filterContext.HttpContext.Response.End();

var unauthorizedResult = new JsonResult
{
    Data = new ErrorResult() {Success = 0, Error = "Forbidden"},
            JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
    // status code
    filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
    // return data
    filterContext.Result = unauthorizedResult;
    filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
}

Ответ 3

Ваша проблема не в запросе AJAX, ваша проблема возвращает HTTP 401 Несанкционированный ответ, потому что вы используете проверку подлинности на основе форм. Этот код ответа сообщает инфраструктуре, что он должен перенаправить пользовательский агент на вашу страницу входа с ответом HTTP 302. Вот почему было легко настроить "нормальный" запрос на перенаправление - это было сделано автоматически.
Чтобы ответить на ваш вопрос, у меня была схожая проблема, и решение, с которым я закончил, не использовало проверку подлинности на основе форм. Я применил специальный атрибут авторизации, который обрабатывает оба случая вручную. Я не уверен, что это лучший подход, но он работает. Меня интересуют, что другие думают об этом решении или о том, какие другие решения есть.
К счастью, вы все равно можете использовать класс FormsAuthentication для обработки файлов cookie для вас, но вам нужно удалить конфигурацию проверки форм из файла Web.config. Когда пользователь входит в систему, вы используете FormsAuthentication.SetAuthCookie, чтобы установить cookie (возможно, вы это уже делаете). Во-вторых, в вашем атрибуте авторизации вы получаете cookie из запроса и используете FormsAuthentication.Decrypt для его расшифровки. Если он существует и действителен, вы устанавливаете пользователя в HttpContext на основе этого куки файла, потому что проверка подлинности форм больше не будет для вас. Если вы не переадресовываете страницу входа или не возвращаете 401, в зависимости от того, является ли она вызовом AJAX или нет.

Ответ 4

Вы можете использовать ajaxonly, чтобы ограничить доступ к ajax actionresult

Ответ 5

Вы можете просто вернуть HttpUnauthorizedResult.

Примечание. Это может привести к тому, что структура MVC вернет вас на страницу входа.

public ActionResult FailResult()
{
        return new HttpUnauthorizedResult();
}

Ответ 6

простым способом является проверка в действии SignIn

public ActionResult SignIn()
{
    if (Request.IsAjaxRequest())
    {
        // you could return a partial view that has this script instead
        return Content("<script>window.location = '" + Url.Action("SignIn", "Account") + "'</script>");
    }
   ...
   return View();