C # MVC Реализация API с параметрами подписи HMAC - PullRequest
3 голосов
/ 20 июля 2011

Я реализую API с использованием аутентификации на основе этой статьи:

http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/

И этот связанный ответ того же автора Реализация двухстороннего поставщика OAuth

У меня есть такая рабочая концепция в API, где параметр подписи - это HAAC SHA256 параметра ключа, сгенерированного с использованием личного ключа клиента:

[HttpGet] [ActionName("List")]
public ActionResult ListGet(string key, string signature)
{
   string serverSignature = GetSignature(key);
   if (serverSignature != signature)
   {
   throw new ArgumentException("Invalid signature", signature);
   }
   // get and return the list
}

Часть HMAC работает отлично, я могу сгенерировать подпись на клиенте и сравнить ее с ожидаемой подписью на сервере.

НО этот новый параметр signature должен применяться к каждому отдельному вызову API. Есть ли способ в MVC 2 сделать это в общем виде, вместо того, чтобы вручную добавлять параметр подписи и проверочный код подписи в каждый метод действия?

Т.е. есть ли возможность избежать записи этого в каждом действии каждого контроллера:

public ActionResult List(string key, string signature) { GetSignature(key); // etc } 
public ActionResult Add(string key, string signature) { GetSignature(key); // etc } 
public ActionResult Update(string key, int id, string signature) { GetSignature(key, id); // etc} 
public ActionResult Delete(string key, int id, string signature) { GetSignature(key, id); // etc} 
public ActionResult Action1(string key, string x, string signature) { GetSignature(key, x);//etc} 

Мне кажется очень неправильным повторять один и тот же кусок кода (DRY!). Есть ли лучший способ?

1 Ответ

2 голосов
/ 20 июля 2011

Вы можете создать собственный атрибут для его хранения и проверки;

    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    public class Securitycheck : ActionFilterAttribute {
        public Securitycheck (String key, String sig) {
        }
        public override void OnActionExecuting(ActionExecutingContext filterContext) {
            base.OnActionExecuting(filterContext);
            if (failed) {
               filterContext.Result = new RedirectResult(redirect);
            }
        }
    }
...