1

2-legged OAuth を前提として、独自の Web サービスを構築しています。

認証された各リクエストには、含まれる HMAC があります。

私はそれが次のようにできることを知っています:

public ActionResult userInfoExample(string HMAC, string username)
    {
        MyMembership.checkHMAC(HMAC);
        //get user
        return View();
    }

HMAC はすべてのアクションのパラメーターに含める必要があるためです。その弱く型付けされ、がらくた。

私はこのようなことをしたかった:

[AuthorizeHMAC]
    public ActionResult userInfoExample(string username)
    {
        //get user
        return View();
    }

私はこれを見つけました、そしてそれは私がカスタムモーダルバインダーを見るべきだと言ったので、私はこれを見つけました、そしてそれを読んだ後、私はそれをどのように機能させることができるかわかりません.

私の目標は、URLパラメーターに配置されている(私が推測する)HMACを使用して認証(/承認)することです。つまり、 http://www.website.com/foo/bar?username=xxx&hmac=xxxxxxxxx

誰かが私が読むことができる参照または直接的な解決策を持っているかどうか知りたい.
また、API セキュリティの基本的な理解、または私がどのように物事を行っているかについての批判を歓迎します。私はこの分野にはかなり慣れていません。

4

1 に答える 1

1

http://mvcsecurity.codeplex.com/で私のコードをチェックして ください

ページ上のパラメーターを検証するのと同じようなことをします(ただし、HMACではありません)。ビューImで生成する(またはビューに渡す)ので、属性でチェックするのと同じ方法でチェックできます。

から:


        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //The hidden form field that contains our hash - for ex. CustomerId is rendered as a hidden input  id="_CustomerIdToken"
            string encryptedPropertyName = string.Format("_{0}Token", _propertyName);

            //grab the token
            string hashToken = filterContext.HttpContext.Request.Form[encryptedPropertyName];

            //The encrypted form data MUST be there. We do not allow empty strings otherwise this could give
            //an attack vector in our filter as a means to bypass checks by simply passing in an empty validation token.
            if (string.IsNullOrEmpty(hashToken))
            {
                throw new MissingFieldException(string.Format("The hidden form field named value {0} was missing. This is created by the Html.AntiModelInjection methods. Ensure the name used on your [ValidateAntiModelInjectionAttribute(\"!HERE!\")] matches the field name used in Html.AntiModelInjection method. If this attribute is used on a controller method that is meant for HttpGet, then the form value would not yet exist. This attribute is meant to be used on controller methods accessed via HttpPost.", encryptedPropertyName));
            }


            //Get the plain text value
            string formValue = filterContext.HttpContext.Request.Form[_propertyName];

            //Plain text must be available to compare.
            if (string.IsNullOrEmpty(formValue))
            {
                throw new MissingFieldException(string.Format("The form value {0} was missing. If this attribute is used on a controller method that is meant for HttpGet, then the form value would not yet exist. This attribute is meant to be used on controller methods accessed via HttpPost.", _propertyName));
            }


            //We cannot encrypt the form value and compare to the previously encrypted form token.
            //Each time you Encrypt() with the MachineKey class even using the same plain text, the end result is difference.
            byte[] plainTextBytes = MachineKey.Decode(hashToken, MachineKeyProtection.Encryption);

            string plainText = Encoding.Unicode.GetString(plainTextBytes);

            //And compare
            if (string.Compare(plainText, formValue , false, CultureInfo.InvariantCulture) != 0)
            {
                throw new HttpAntiModelInjectionException(string.Format("Failed security validation for {0}. It is possible the data was tampered with as the original value used to create the form field does not match the current property value for this field. Ensure if this is a web farm, the machine keys are the same.",_propertyName));
            }


            filterContext.HttpContext.Trace.Write("(Logging Filter)Action Executing: " +
                filterContext.ActionDescriptor.ActionName);

            base.OnActionExecuting(filterContext);
        }

于 2012-04-13T06:01:22.837 に答える