С# https войти и скачать файл

Я успешно подключился к странице входа в систему, однако я не уверен, как войти в систему и получить файл, который стоит за входом в систему. Ниже приведен код, который я использую для подключения.

  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:\test.xls");

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

    }

Я уверен, что загрузка не работает, и я уверен, что String postData не выполняет то, для чего предназначен.

Ниже приведен код для входа на сайт

<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>

И файл, который я хочу скачать, находится по этой ссылке https://app/template/simple%2Screen.vm

Я могу подключиться к веб-странице, но не знаю, как войти и скачать файл.

Пожалуйста, смотрите обновление кода. Это все еще не входит в систему, и я не уверен, почему.

 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();
            }

Это новый код, есть 1 файл cookie, однако, когда я пытаюсь сделать первый пост, он никогда не входит в систему.


person Community    schedule 23.03.2012    source источник


Ответы (2)


В вашем коде есть следующие проблемы, которые я вижу:

  1. Неправильно обрабатывает контейнер cookie. CookieContainer должен быть инициализирован, а затем передан вашему HttpWebRequest, а не наоборот.
  2. Не очищает одноразовые предметы. Неспособность удалить объект может привести к тому, что объект зависнет на некоторое время, прежде чем сборщик мусора его догонит.
  3. Не учитывает действие формы. Ваше действие формы вызовет отправку в другое место.
  4. Без необходимости выполняет первую операцию как POST. Вместо этого используйте GET.
  5. Не устанавливает ссылку при выполнении операции POST.

Попробуйте следующий код:

    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!");
    }       
person JamieSee    schedule 23.03.2012
comment
да, так что, если бы я хотел перейти по URL-адресу под URL-адресом /mgr/app/action/storeVivolAction/eventsubmit_dopreparevivollist/ignored, как бы я продолжил это? Должен ли я производить больше файлов cookie? - person ; 23.03.2012
comment
Просто сделайте еще один запрос для следующего URL-адреса, который вы хотите посетить, и продолжайте использовать тот же контейнер файлов cookie request.CookieContainer = cookieJar;. Если вы не отправляете данные на сервер, убедитесь, что вы используете метод запроса GET. Вы должны продолжать использовать тот же контейнер файлов cookie для любых дополнительных веб-запросов, составляющих один сеанс. - person JamieSee; 24.03.2012

Во-первых, вам нужно инициировать контейнер cookie перед первым запросом:

CookieContainer cookies = new CookieContainer();

затем вам нужно передавать его по каждому запросу (теперь вы просто создаете его снова, теряя при этом все файлы cookie):

request.CookieContainer = cookies;

полученный вами ответ заполнит контейнер cookie необходимыми файлами cookie.

Кроме того, как я вижу, вы уже делаете это, вам необходимо выполнить серию запросов/ответов на веб-сайте и отслеживать файлы cookie. Используйте такой инструмент, как Fiddler, чтобы увидеть, как именно вам нужно сформулировать строки POST для правильного входа в систему. Веб-сайт.

person TheBoyan    schedule 23.03.2012
comment
Я думал, что это то, что я здесь делаю cookies = request.CookieContainer; - person ; 23.03.2012
comment
@Mike - можете ли вы отладить и посмотреть, действительно ли он заполняет файлы cookie, мне кажется, что, делая это, вы можете перезаписать их. - person TheBoyan; 23.03.2012
comment
@Mike - если все выглядит хорошо, то во втором запросе прочитайте ответ и файлы cookie (это будет означать, что вы вошли в систему), а затем выполните еще один, чтобы загрузить файл. - person TheBoyan; 23.03.2012
comment
Я думаю, что проблема в том, что он никогда не пытается войти в систему, когда я читаю SR.toend, это страница входа в систему. - person ; 23.03.2012
comment
У меня есть, и он продолжает оставаться при входе в систему, я не уверен, как я вообще публикую учетные данные - person ; 23.03.2012
comment
когда сможешь, можешь взглянуть на обновление, я убедился, что куки есть - person ; 23.03.2012
comment
@Mike - попробуйте Fiddler, он даст вам представление о GET/POST... а затем попытайтесь воспроизвести шаги в своем коде, используя HttpWebRequest/HttpWebResponse. - person TheBoyan; 23.03.2012