C# POST访问需要HTTP Digest Authentication认证资源的实现

 在你访问一个需要HTTP Digest Authentication的URL的时候,如果你没有提供用户名和密码,服务器就会返回401,如果你直接在浏览器中打开,浏览器会提示你输入用户名和密码;要在发送请求的时候添加HTTP Digest Authentication认证信息到请求中,有两种方法:

  • 一是在请求头中添加Authorization: Authorization: "Digest 用户名和密码的base64加密字符串"
  • 二是在url中添加用户名和密码: http://userName:password@XXX

       除去最常用的GET,当使用需要账户密码访问的站点功能时(比如以http形式访问的短信网关)常常需要POST相应信息(无论它的消息格式是什么),下面是封装好的一个方法:

 

public int PostRequest(string Url, string user, string pwd, string paramData, Encoding MsgEncode)
        {
            if (string.IsNullOrEmpty(Url))
            {
                throw new ArgumentNullException("Url");
            }
            if (MsgEncode == null)
            {
                throw new ArgumentNullException("MsgEncoding");
            }

            string username = user;
            string password = pwd;
            string usernamePassword = username + ":" + password;
            CredentialCache mycache = new CredentialCache();
            mycache.Add(new Uri(Url), "Digest", new NetworkCredential(username, password));

            Logger.INFO(GetType().ToString(), "PostRequest", "POST HTTP请求,创建短信请求", string.Empty);
            HttpWebRequest Request = (HttpWebRequest)WebRequest.Create(new Uri(Url));
            Request.Credentials = mycache;
            Request.Headers.Add("Authorization", "Digest" + Convert.ToBase64String(MsgEncode.GetBytes(usernamePassword)));

            Request.Method = "POST";
            //Request.Timeout = 1000;
            Request.ContentType = "application/x-www-form-urlencoded";

            string temp_paramData = "json = " + System.Web.HttpUtility.UrlEncode(paramData);
            byte[] byteArray = MsgEncode.GetBytes(temp_paramData);
            Request.ContentLength = byteArray.Length;

            Stream newStream = Request.GetRequestStream();
            newStream.Write(byteArray, 0, byteArray.Length);
            newStream.Close();

            //string ret = string.Empty;
            Logger.INFO(GetType().ToString(), "PostRequest", "POST HTTP请求,获取短信HTTP请求响应", string.Empty);
            HttpWebResponse response;
            try
            {
                response = (HttpWebResponse)Request.GetResponse();
            }
            catch (WebException ex)
            {
                response = (HttpWebResponse)ex.Response;
            }

            int ret = 0;
            ret = (int)response.StatusCode;
            Logger.INFO(GetType().ToString(), "PostRequest", "POST HTTP请求,发送短信请求返回状态码", ret.ToString() + ParaHttpResult(ret));

            Stream stream = response.GetResponseStream();
            byte[] rsByte = new Byte[response.ContentLength];
            //StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default);
            //ret = sr.ReadToEnd();
            try
            {
                stream.Read(rsByte, 0, (int)response.ContentLength);
                Logger.INFO(GetType().ToString(), "PostRequest", "POST HTTP请求,发送短信请求返回内容", System.Text.Encoding.UTF8.GetString(rsByte, 0, rsByte.Length).ToString());
            }
            catch (Exception ex)
            {
                Logger.ERROR(GetType().ToString(), "PostRequest", "POST HTTP请求,发送短信请求返回内容异常", ex.ToString());
            }
            stream.Close();
            response.Close();

            return ret;
        }

 

第一个参数是接受http访问的url,第二第三参数分别是用户名密码,第四个参数是消息内容,第五个参数是消息内容的编码格式,关于认证的三种方式和C#相应的类可以查阅基于C#的http协议开发,该方法采用的是Digest摘要认证形式,而且消息体格式为json;关于http请求消息的写入和http响应的获取可以查看该方法的实现与MSDN结合看,这样会有一个比较全面的认识。

 

       最后该方法的返回参数为http响应的状态码即200、401等,response.StatusCode是一个枚举,如果不进行转换获得的是 OK、NotFound 这样的名称。

 

posted @ 2014-08-30 03:28  江伟  阅读(5165)  评论(0编辑  收藏  举报