I'm implementing an API using authentication based on this article:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
And this related answer by the same author Implementing a 2 Legged OAuth Provider
I have a working concept in the API like so, where the signature parameter is a SHA256 HMAC of the key parameter, generated using the clients private key:
[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
}
The HMAC portion works perfectly, I am able to generate the signature on the client and compare it to the expected signature on the server.
BUT this new parameter signature
needs to be applied to every single API call. Is there any way in MVC 2 to do this in a generic manner, instead of having to manually add the signature parameter and the check signature code to every single action method?
Ie is there anyway to avoid having to write this in every single action of every single controller:
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}
It looks very wrong to me to have the same piece of code repeated like that (DRY!). Is there a better way?
You could create a custom attribute to store it and check it;
[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);
}
}
}
精彩评论