.net 通过AuthorizeAttribute 验证访问有效性

基本思路和验证的方案,网上有很多案例,这里就不展开描述了

主要思路就是:自定义权限验证类,它需要继承自:AuthorizeAttribute   

然后重写基类验证方法

public async override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext context)
{

}

另外就是,需要在Controller头部标识  是否需要进行权限验证

 

 

 

这里重点讲一下客户端发送get、post请求后,如果要验证请求参数如何处理

1、get请求的参数获取

//获取请求参数
                        var dict = context.Request.GetQueryNameValuePairs().ToList();
                        if (dict.Count > 0)
                        {
                            Dictionary<string, string> dictInfo = new Dictionary<string, string>();
                            foreach (var item in dict)
                            {
                                dictInfo.Add(item.Key.ToString(), item.Value.ToString());
                            }
                            //获取组装后的data
                            data = GetStr(dictInfo);
                        }
View Code

如上所示,就获取了带排序功能的参数字符串

 

2、post请求的参数获取

   a、application/json形式参数获取

//代码待完善
                            Dictionary<string, string> dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(content);
                            //获取组装后的data
                            data = GetStr(dict);
View Code

 

   b、application/x-www-form-urlencoded形式提交的参数获取

string[] array = content.Split('&');
                            Dictionary<string, string> dict = new Dictionary<string, string>();
                            foreach (var item in array)
                            {
                                dict.Add(item.ToString().Split('=')[0], item.ToString().Split('=')[1]);
                            }
                            //获取组装后的data
                            data = GetStr(dict);
View Code

 

   c、multipart/form-data 形式提交的参数获取

这里需要用到一个自定义内存中的MultiaprtFormDataStreamProvider,它继承自MultipartStreamProvider

InMemoryMultipartFormDataStreamProvider类如下:

/// <summary>
    /// 自定义内存中的MultiaprtFormDataStreamProvider
    /// </summary>
    public class InMemoryMultipartFormDataStreamProvider : MultipartStreamProvider
    {
        private NameValueCollection _formData = new NameValueCollection();
        private List<HttpContent> _fileContents = new List<HttpContent>();

        // Set of indexes of which HttpContents we designate as form data
        private Collection<bool> _isFormData = new Collection<bool>();

        /// <summary>
        /// Gets a <see cref="NameValueCollection"/> of form data passed as part of the multipart form data.
        /// </summary>
        public NameValueCollection FormData
        {
            get { return _formData; }
        }

        /// <summary>
        /// Gets list of <see cref="HttpContent"/>s which contain uploaded files as in-memory representation.
        /// </summary>
        public List<HttpContent> Files
        {
            get { return _fileContents; }
        }

        public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
        {
            // For form data, Content-Disposition header is a requirement
            ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;
            if (contentDisposition != null)
            {
                // We will post process this as form data
                _isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));

                return new MemoryStream();
            }

            // If no Content-Disposition header was present.
            throw new InvalidOperationException(string.Format("Did not find required '{0}' header field in MIME multipart body part..", "Content-Disposition"));
        }

        /// <summary>
        /// Read the non-file contents as form data.
        /// </summary>
        /// <returns></returns>
        public override async Task ExecutePostProcessingAsync()
        {
            // Find instances of non-file HttpContents and read them asynchronously
            // to get the string content and then add that as form data
            for (int index = 0; index < Contents.Count; index++)
            {
                if (_isFormData[index])
                {
                    HttpContent formContent = Contents[index];
                    // Extract name from Content-Disposition header. We know from earlier that the header is present.
                    ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition;
                    string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty;

                    // Read the contents as string data and add to form data
                    string formFieldValue = await formContent.ReadAsStringAsync();
                    FormData.Add(formFieldName, formFieldValue);
                }
                else
                {
                    _fileContents.Add(Contents[index]);
                }
            }
        }

        /// <summary>
        /// Remove bounding quotes on a token if present
        /// </summary>
        /// <param name="token">Token to unquote.</param>
        /// <returns>Unquoted token.</returns>
        private static string UnquoteToken(string token)
        {
            if (String.IsNullOrWhiteSpace(token))
            {
                return token;
            }

            if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
            {
                return token.Substring(1, token.Length - 2);
            }

            return token;
        }
    }
View Code

具体使用和获取参数请求代码:

var provider = await context.Request.Content.ReadAsMultipartAsync<InMemoryMultipartFormDataStreamProvider>(new InMemoryMultipartFormDataStreamProvider());
                            NameValueCollection formData = provider.FormData;
                            Dictionary<string, string> dict = new Dictionary<string, string>();
                            foreach (var item in formData)
                            {
                                string key = item.ToString();
                                string value = formData[item.ToString()];
                                dict.Add(key, value);
                            }
                            //获取组装后的data
                            data = GetStr(dict);

                            #region  访问文件的方法(已注释)
                            //access files
                            //IList<HttpContent> files = provider.Files;

                            ////Example: reading a file's stream like below
                            //HttpContent file1 = files[0];
                            //Stream file1Stream = await file1.ReadAsStreamAsync();
                            #endregion
View Code

 

最后附GetStr()方法

private static string GetStr(Dictionary<string, string> dict)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var item in dict.OrderBy(a => a.Key))
            {
                sb.AppendFormat("{0}{1}{2}{3}", item.Key, ApiCommonHelper.NameValueSeparator, item.Value, ApiCommonHelper.SpaceSeparator);
            }
            return sb.ToString().Substring(0, sb.ToString().Count() - 1);
        }
View Code

 

获取了请求参数,做验签操作自然也就不难了。

 

InMemoryMultipartFormDataStreamProvider实现参考自:

http://www.voidcn.com/article/p-zrmjyzmd-bsr.html

 

posted @ 2021-10-22 10:54  狼窝窝  阅读(195)  评论(0)    收藏  举报