Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
606 views
in Technique[技术] by (71.8m points)

httpwebrequest - C# https login and download file

I have successful connected to the login page, however, i'm not sure how to login and grab the file thats behind the login. Below is the code i'm using to make the connect.

  private static bool bypassAllCertificateStuff(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)
    {
        return true;
    }


    public static void Processing()
    {
        string url = "https://app/templat";
        HttpWebRequest request;
        HttpWebResponse response;
        CookieContainer cookies;
        ServicePointManager.ServerCertificateValidationCallback =
        System.Net.ServicePointManager.ServerCertificateValidationCallback =
        ((sender, certificate, chain, sslPolicyErrors) => true);
        System.Net.ServicePointManager.ServerCertificateValidationCallback
            = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));
        ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(bypassAllCertificateStuff);
        try
        {
            request = (HttpWebRequest)WebRequest.Create(url);
            request.AllowAutoRedirect = false;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.CookieContainer = new CookieContainer();
            response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK)
            {
                cookies = request.CookieContainer;



                request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";

                String postData = "j_login=user&j_password=user&submit=Send";
                byte[] data = System.Text.ASCIIEncoding.ASCII.GetBytes(postData);
                request.ContentLength = data.Length;
                //Stream stream = request.GetRequestStream();
                //stream.Write(data, 0, data.Length);

                request.CookieContainer = cookies;

                //stream.Close();
                StreamReader sr = new StreamReader(response.GetResponseStream());
                string tmp = sr.ReadToEnd().Trim();


                //response = (HttpWebResponse)request.GetResponse();
                //WebClient wbClient = new WebClient();
                //wbClient.DownloadFile("https://app/template/simple%2Screen.vm", @"C:est.xls");

                response.Close();
            }
            else
            {
                Console.WriteLine("Client was unable to connect!");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

    }

I'm positive the download doesn't work and i'm sure String postData doesn't perform what intend it to.

Below is the code for the website login

<pre>
<form name="loginform" method="post" action="j_security_check" onSubmit="javascript:fixFields();">
<br>
<table border="0" cellpadding="5" cellspacing="0" width="80%">
<tr>
<td colspan="2" align="center" nowrap="nowrap">
<div id="bannerDiv" class="groupingBorder" style="visibility:hidden;position:relative;background-color:#FFFFFF; overflow:auto;">
</div>
</td>

</tr>
<tr>
<td class="contentrtanbld" nowrap width="50%">Name:</td>
 <td class="contentltan" nowrap width="50%">
<input type="text" name="j_username" id="j_username" value="" class="authGroupWidth" size="20"></td>
 </tr>
<tr>
<td class="contentrtanbld" nowrap>Password:</td>
<td class="contentltan" nowrap>
<input type="password" name="j_password" id="j_password" value="" class="authGroupWidth" size="20"></td>
</tr>
<tr>
</pre>

And the file I want to download is via this link https://app/template/simple%2Screen.vm

I'm able to make the connection to the webpage but i'm unsure how to login and download the file.

Please see update to code. This is still not logging in and i'm not sure why.

 string url = "https://mgr/app";
        HttpWebRequest request;
        HttpWebResponse response;
        CookieContainer cookies = new CookieContainer();
        ServicePointManager.ServerCertificateValidationCallback =
        System.Net.ServicePointManager.ServerCertificateValidationCallback =
        ((sender, certificate, chain, sslPolicyErrors) => true);
        System.Net.ServicePointManager.ServerCertificateValidationCallback
            = ((sender, cert, chain, errors) => cert.Subject.Contains("YourServerName"));
        ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(bypassAllCertificateStuff);
        try
        {
            string cookieHeader;
            string formParams = string.Format("j_login={0}&j_password={1}", "user", "user");
            request = (HttpWebRequest)WebRequest.Create(url);
            request.ContentType = "application/x-www-form-urlencoded";
            request.Method = "POST";
            byte[] bytes = Encoding.ASCII.GetBytes(formParams);
            request.ContentLength = bytes.Length;
            using (Stream os = request.GetRequestStream())
            {
                os.Write(bytes, 0, bytes.Length);
            }
            WebResponse resp = request.GetResponse();
            cookieHeader = resp.Headers["Set-cookie"];

            string pageSource;
            string BehinPath = "https://mgr/app/action/store.VivolAction/eventsubmit_dopreparevivollist/ignored";
            WebRequest getRequest = WebRequest.Create(BehinPath);
            getRequest.Headers.Add("Cookie", cookieHeader);
            WebResponse getResponse = getRequest.GetResponse();
            using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
            {
                pageSource = sr.ReadToEnd();
            }

This is the new code, there is 1 cookie, however when i try the first post it never logs in.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your code has the following problems that I can see:

  1. Doesn't properly handle the cookie container. CookieContainer should be initialized and then passed to your HttpWebRequest, not the other way around.
  2. Does not cleanup disposable objects. Failing to dispose an object can result in the object hanging around for quite a while before the garbage collector catches up with it.
  3. Does not account for the form action. Your form action will cause a submit to a different location.
  4. Unnecessarily performs the first operation as a POST. Use GET instead.
  5. Does not set the referer when performing the POST operation.

Try the following code:

    Uri url = new Uri("http://app/templat");
    HttpWebRequest request = null;

    // Uncomment the line below only if you need to accept an invalid certificate, i.e. a self-signed cert for testing.
    // ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true);
    CookieContainer cookieJar = new CookieContainer();

    request = (HttpWebRequest)WebRequest.Create(url);
    request.CookieContainer = cookieJar;
    request.Method = "GET";
    HttpStatusCode responseStatus;

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        responseStatus = response.StatusCode;
        url = request.Address;
    }

    if (responseStatus == HttpStatusCode.OK)
    {
        UriBuilder urlBuilder = new UriBuilder(url);
        urlBuilder.Path = urlBuilder.Path.Remove(urlBuilder.Path.LastIndexOf('/')) + "/j_security_check";

        request = (HttpWebRequest)WebRequest.Create(urlBuilder.ToString());
        request.Referer = url.ToString();
        request.CookieContainer = cookieJar;
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";

        using (Stream requestStream = request.GetRequestStream())
        using (StreamWriter requestWriter = new StreamWriter(requestStream, Encoding.ASCII))
        {
            string postData = "j_username=user&j_password=user&submit=Send";
            requestWriter.Write(postData);
        }

        string responseContent = null;

        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        using (Stream responseStream = response.GetResponseStream())
        using (StreamReader responseReader = new StreamReader(responseStream))
        {
            responseContent = responseReader.ReadToEnd();
        }

        Console.WriteLine(responseContent);
    }
    else
    {
        Console.WriteLine("Client was unable to connect!");
    }       

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...