c# - WebRequest HTTP POST with Cookie (port from curl script)

谁都会走 提交于 2019-12-02 16:24:39

I would suggest you try the following:

public class WebClientEx : WebClient
{
    private CookieContainer _cookieContainer = new CookieContainer();

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        if (request is HttpWebRequest)
        {
            (request as HttpWebRequest).CookieContainer = _cookieContainer;
        }
        return request;
    }
}

class Program
{
    static void Main()
    {
        using (var client = new WebClientEx())
        {
            var response1 = client.DownloadString("https://myJazzServer.com:9092/jazz/authenticated/identity");

            var data = new NameValueCollection
            {
                { "j_username", "myUser" },
                { "j_password", "MyPass" },
            };
            var response2 = client.UploadValues("https://myJazzServer.com:9092/jazz/authenticated/j_security_check", data);
            Console.WriteLine(Encoding.Default.GetString(response2));
        }
    }
}

Also to simplify debugging you could activate tracing by putting this in your app.config:

<configuration>

  <system.diagnostics>
    <sources>
      <source name="System.Net.Sockets" tracemode="protocolonly">
        <listeners>
          <add name="System.Net.Sockets" type="System.Diagnostics.TextWriterTraceListener" initializeData="network.log" />
        </listeners>
      </source>
    </sources>

    <switches>
      <add name="System.Net.Sockets" value="Verbose"/>
    </switches>

    <trace autoflush="true" />
  </system.diagnostics>
</configuration>

This will create a detailed log file of the network activity which might simplify debugging.

Navneet Kumar

Here is an alternative method if you want to use HttpWebResponse/HttpWebRequest:

public static HttpWebResponse requestSecureDocument(HttpWebRequest _request, string _rtcServerURL, string _userName, string _password)
{
    //FormBasedAuth Step1: Request the resource and clone the request to be used later
    HttpWebRequest _requestClone = WebRequestExtensions.CloneRequest(_request, _request.RequestUri);
    //(HttpWebRequest)WebRequest.Create(request.RequestUri);

    //store the response in _docResponse variable
    HttpWebResponse _docResponse = (HttpWebResponse)_request.GetResponse();

    //HttpStatusCode.OK indicates that the request succeeded and that the requested information is in the response.
    if (_docResponse.StatusCode == HttpStatusCode.OK)
    {
        //X-com-ibm-team-repository-web-auth-msg header signifies form based authentication is being used
        string _rtcAuthHeader = _docResponse.Headers["X-com-ibm-team-repository-web-auth-msg"];
        if (_rtcAuthHeader != null && _rtcAuthHeader.Equals("authrequired"))
        {
            _docResponse.GetResponseStream().Flush();
            _docResponse.Close();

            //Prepare form for authentication as _rtcAuthHeader = authrequired
            HttpWebRequest _formPost = (HttpWebRequest)WebRequest.Create(_rtcServerURL + "/j_security_check");
            _formPost.Method = "POST";
            _formPost.Timeout = 30000;
            _formPost.CookieContainer = _request.CookieContainer;
            _formPost.Accept = "text/xml";
            _formPost.ContentType = "application/x-www-form-urlencoded";

            String _authString = "j_username=" + _userName + "&amp;j_password=" + _password;
            //create authentication string
            Byte[] _outBuffer = Encoding.UTF8.GetBytes(_authString); //store in byte buffer
            _formPost.ContentLength = _outBuffer.Length;
            Stream _str = _formPost.GetRequestStream();
            _str.Write(_outBuffer, 0, _outBuffer.Length); //update form
            _str.Close();

            //FormBasedAuth Step2:submit the login form and get the response from the server
            HttpWebResponse _formResponse = (HttpWebResponse)_formPost.GetResponse();

            _rtcAuthHeader = _formResponse.Headers["X-com-ibm-team-repository-web-auth-msg"];
            //check if authentication has failed
            if (_rtcAuthHeader != null && _rtcAuthHeader.Equals("authfailed"))
            {
                //authentication failed. You can write code to handle the authentication failure.
                //if (DEBUG) Console.WriteLine("Authentication Failure");
            }
            else
            {
                //login successful
                _formResponse.GetResponseStream().Flush();
                _formResponse.Close();
                //FormBasedAuth Step3: Resend the request for the protected resource.
                //if (DEBUG) Console.WriteLine("&gt;&gt; Response " + request.RequestUri);
                return (HttpWebResponse)_requestClone.GetResponse();
            }
        }
    }
    //already authenticated return original response_docResponse
    return _docResponse;
}

You can call this function in your code -

string _serverURL = https://localhost:9443/ccm; 
string _resourceURL = "https://localhost:9443/ccm/rootservices";

string mediatype = "application/xml";
string username = "username";                                    
string password = "password";
try
{
    CookieContainer _cookies = new CookieContainer();//create cookie container
    HttpWebRequest documentGet = (HttpWebRequest)WebRequest.Create(_resourceURL);
    documentGet.Method = "GET"; //method
    documentGet.CookieContainer = _cookies; //set container for HttpWebRequest 
    documentGet.Accept = mediatype;
    documentGet.Headers.Set("OSLC-Core-Version", "3.0"); //for RTC 3.0.1.2
    documentGet.Timeout = 300000;
    HttpWebResponse response = requestSecureDocument(documentGet, _serverURL, username, password);

    if (response.StatusCode != HttpStatusCode.OK)
    {
        Console.WriteLine(" Error: " + response.StatusDescription);
        response.Close();
    }
}
catch (Exception ex)
{
}

You can read more at my blog.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!