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

后端 未结 2 1489
清酒与你
清酒与你 2021-01-31 00:08

The IBM RTC RESTful api gives an example of a shell script for authenticating with the server:

COOKIES=./cookies.txt

USER=my_user
PASSWORD=my_password
HOST=\"ht         


        
相关标签:
2条回答
  • 2021-01-31 00:52

    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.

    0 讨论(0)
  • 2021-01-31 01:05

    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.

    0 讨论(0)
提交回复
热议问题