2016-01-29 2 views
2

Мой вопрос очень прямо вперед ...Set ValidateAntiForgeryToken приписывать GET/POST для таких же действий MVC5

У меня есть Action, который принимает как HttpGet и HttpPost, но я хочу, чтобы установить атрибут ValidateAntiForgeryToken к действию, когда http-запрос POST, а не для HttpGet.

Я могу найти, является ли запрос GET или POST внутри действия, но мне нужно знать перед вызовом.

[ValidateAntiForgeryToken] // Only for HttpPost 
    public ActionResult Index() // Allows HttpPost/HttpGet 
    { 

    } 

Есть ли возможности достичь этого без дублирования действия?

Спасибо

ответ

6

Можно условно метод проверки HTTP просьбе и вручную делать проверки достоверности себя:

if (Request.Method.ToLower() == "post") 
{ 
    System.Web.Helpers.AntiForgery.Validate(); 
} 
+0

работает, хотя используется, если (Request.HttpMethod == WebRequestMethods.Http.Post) вместо этого для оператора if в качестве Request.Method не существует в контроллере –

1

Там ничего уже встроено в рамки, которые будут в настоящее время позволит вам это сделать, но вы все еще есть один вариант. Создайте собственную реализацию ValidateAntiForgeryToken, которая принимает параметр http verb/actions, на который вы хотите его проверить. Самый простой способ - реализовать интерфейс IAuthorizationFilter.

+0

@lgor, Спасибо за ваш быстрый ответ. Но я получил более лучшее решение, которое я назвал ответом. – Shanthini

+0

@Shanthini - это хороший ответ и его легко реализовать, но если вам нужно сделать это по многим методам, тогда один раз один раз в пользовательском 'Filter' код будет лучшим и более удобным для обслуживания решением, чем добавление вышеприведенного оператора' if' ко всем ваших методов. – Igor

+0

@lgor Да. Согласен. Но на данный момент у меня была эта проблема только в одном сценарии :) Но я создал собственный фильтр для будущей ссылки; не используя его сейчас. – Shanthini

1

Вы имеете возможность обнаружить это see link:

if (HttpContext.Current.Request.HttpMethod == "POST") 
{ 
    // The action is a POST. 
} 

и вам нужен атрибут метода для перехвата перед действием выполнения и принять другое поведение, чтобы пропустить действие. ValidateAntiForgeryToken не работает на GETUsing MVC3's AntiForgeryToken in HTTP GET to avoid Javascript CSRF vulnerability.

1

Во-первых, это очень плохой дизайн. Точка MVC - это разделение методов в контроллере. Если вы хотите, чтобы два метода имели одно и то же поведение, я предлагаю изменить ваш контроллер на наличие GET и POST, каждый из которых вызывает один и тот же метод в другом месте контроллера.

Но вы можете написать атрибут Validation, чтобы выполнить то, что вы хотите.

Исходя из этого source code, вы могли бы изменить метод OnAuthorization в Validation приписывать:

public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     var request = filterContext.HttpContext.Request.HttpMethod; 
     if (request != "GET") 
     { 
      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      ValidateAction(); 
     } 
    } 

, который проверяет, чтобы увидеть, если запрос GET в этом случае он пропускает проверку. Полный класс Атрибут является:

using System.ComponentModel; 
using System.Diagnostics; 
using System.Diagnostics.CodeAnalysis; 
using System.Web.Helpers; 

namespace System.Web.Mvc 
{ 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public sealed class ValidateAntiForgeryTokenAttribute2 : FilterAttribute, IAuthorizationFilter 
{ 
    private string _salt; 

    public ValidateAntiForgeryTokenAttribute2() 
     : this(AntiForgery.Validate) 
    { 
    } 

    internal ValidateAntiForgeryTokenAttribute2(Action validateAction) 
    { 
     Debug.Assert(validateAction != null); 
     ValidateAction = validateAction; 
    } 

    [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AdditionalDataProvider", Justification = "API name.")] 
    [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AntiForgeryConfig", Justification = "API name.")] 
    [Obsolete("The 'Salt' property is deprecated. To specify custom data to be embedded within the token, use the static AntiForgeryConfig.AdditionalDataProvider property.", error: true)] 
    [EditorBrowsable(EditorBrowsableState.Never)] 
    public string Salt 
    { 
     get { return _salt; } 
     set 
     { 
      if (!String.IsNullOrEmpty(value)) 
      { 
       throw new NotSupportedException("The 'Salt' property is deprecated. To specify custom data to be embedded within the token, use the static AntiForgeryConfig.AdditionalDataProvider property."); 
      } 
      _salt = value; 
     } 
    } 

    internal Action ValidateAction { get; private set; } 

    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     var request = filterContext.HttpContext.Request.HttpMethod; 
     if (request != "GET") 
     { 
      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      ValidateAction(); 
     } 
    } 
} 

}

Смежные вопросы