Rasi
Rasi

Reputation: 31

POST to HTTPS authentication error

This is a simple post to a https site using C# console app, I used the same thing with webservice too. When I run this it froze. Downloaded the fiddler and in the Auth tab I see No Proxy-Authenticate Header is present. No WWW-Authenticate Header is present.

Earlier I used Stream instead of MemoryStream. I've commented out some of the things I used before but didn't work like preauthenticate.

I can login to the site to get a subscriber thru IE, using the same user and passsword. Can some one please tell me what's wrong?.

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web;

namespace Examples.System.Net
{
    public class WebRequestPostExample
    {
        public static void Main()
        {
            Uri requestUri = new Uri("https://services.yesmail.com/enterprise/subscribers");            

            // Set the Method property of the request to POST.   
            CredentialCache cache = new CredentialCache();
            NetworkCredential nc = new NetworkCredential("user/user1", "password");                 
            cache.Add(requestUri, "Basic", nc);
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUri);

            //request.PreAuthenticate = true;
            //request.KeepAlive = false;

            request.Method = WebRequestMethods.Http.Post;
            request.ContentType = "application/xml;charset=ISO-8859-1";

            //request.ContentType = "application/xml-www-form-urlencoded";       
            //request.Timeout = 300000;


            string EmailAddress = "[email protected]";
            string FirstName = "first";
            string LastName = "Last";

            StringBuilder Efulfill = new StringBuilder();


            Efulfill.Append("EmailAddress" + HttpUtility.UrlEncode(EmailAddress));
            Efulfill.Append("FirstName" + HttpUtility.UrlEncode(FirstName));
            Efulfill.Append("LastName" + HttpUtility.UrlEncode(LastName));


            byte[] byteData = Encoding.UTF8.GetBytes(Efulfill.ToString());

            request.ContentType = "application/xml;charset=ISO-8859-1";

            request.ContentLength = byteData.Length;



            using (MemoryStream Stream = new MemoryStream(byteData))
            {
                // Write the stream.
                Stream.Write(byteData, 0, byteData.Length);
                Stream.Close();
            }
            //Get response   

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream resStream = response.GetResponseStream())
                {
                    StreamReader reader = new StreamReader(resStream, Encoding.Default);
                    Console.WriteLine(reader.ReadToEnd());
                }
            }


        }
    }
}

Upvotes: 3

Views: 6158

Answers (4)

Charlie Wu
Charlie Wu

Reputation: 7757

maybe try to set credential in the request header. I worked on a project where I have to request some data from a web application using spring security and the only way I can get it working is by set credential in the request header.

the code looks something like this:

string authInfo = username + ":" + password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
request.Headers["Authorization"] = "Basic " + authInfo;

for more details see this blog post

http://charlie.cu.cc/2012/05/how-use-basic-http-authentication-c-web-request/

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1039000

Is there any particular reason you would like to write sooooo much code when you could simply:

using (var client = new WebClient())
{
    var requestUri = new Uri("https://services.yesmail.com/enterprise/subscribers");
    var cache = new CredentialCache();
    var nc = new NetworkCredential("user/user1", "password");
    cache.Add(requestUri, "Basic", nc);
    client.Credentials = cache;

    var values = new NameValueCollection
    {
        { "EmailAddress", "[email protected]" },
        { "FirstName", "first" },
        { "LastName", "last" },
    };

    var result = client.UploadValues(requestUri, values);
    Console.WriteLine(Encoding.Default.GetString(result));
}

This will also take care of properly url encoding your request parameters so that you don't have to do it manually.

When I run this I got 401 Unauthorized but I guess that's because the username and password used for basic authentication are dummy.

Upvotes: 1

phillip
phillip

Reputation: 2748

I copied your code and it wouldn't run because you were not doing anything with the posted data stream before getting the response. I've copied the code and it works as expected now. Just subst your real credentials and it is good.

Uri requestUri = new Uri("https://services.yesmail.com/enterprise/subscribers");            

// Set the Method property of the request to POST.   
var cache = new System.Net.CredentialCache();
var nc = new System.Net.NetworkCredential("user/user1", "password");                 
cache.Add(requestUri, "Basic", nc);
var request = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(requestUri);

//request.PreAuthenticate = true;
//request.KeepAlive = false;

request.Method = System.Net.WebRequestMethods.Http.Post;
request.ContentType = "application/xml;charset=ISO-8859-1";

request.ContentType = "application/xml-www-form-urlencoded";       
//request.Timeout = 300000;

string EmailAddress = "[email protected]";
string FirstName = "first";
string LastName = "Last";

StringBuilder Efulfill = new StringBuilder();

Efulfill.Append("EmailAddress" + System.Web.HttpUtility.UrlEncode(EmailAddress));
Efulfill.Append("FirstName" + System.Web.HttpUtility.UrlEncode(FirstName));
Efulfill.Append("LastName" + System.Web.HttpUtility.UrlEncode(LastName));

byte[] byteData = Encoding.UTF8.GetBytes(Efulfill.ToString());

request.ContentType = "application/xml;charset=ISO-8859-1";
request.ContentLength = byteData.Length;

Stream postStream = request.GetRequestStream();
postStream.Write(byteData, 0, byteData.Length);
postStream.Close();

//Get response   

using (var response = (System.Net.HttpWebResponse)request.GetResponse())
{
    using (Stream resStream = response.GetResponseStream())
    {
        StreamReader reader = new StreamReader(resStream, Encoding.Default);
        Console.WriteLine(reader.ReadToEnd());
    }
}

Upvotes: 1

Dark Falcon
Dark Falcon

Reputation: 44191

You are taking the data in byteData and writing it over itself via a MemoryStream? You need to use HttpWebRequest.GetRequestStream to get the stream, write your post data, and make sure it is closed.

Upvotes: 1

Related Questions