2010-07-15 98 views
12

IBM的RTC REST的API給shell腳本的例子與服務器進行身份驗證:C# - WebRequest的HTTP POST與曲奇(端口從捲曲腳本)

COOKIES=./cookies.txt 

USER=my_user 
PASSWORD=my_password 
HOST="https://myJazzServer:9092/jazz" 

curl -k -c $COOKIES "$HOST/authenticated/identity" 

curl -k -L -b $COOKIES -c $COOKIES -d j_username=$USER -d j_password=$PASSWORD "$HOST/authenticated/j_security_check" 

這完美的作品,但我需要驗證與服務器使用C#。

到目前爲止,我有以下的,但它不工作(返回授權失敗頁):

CookieContainer _cookie; 

    public string _RTC() 
    { 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://myJazzServer.com:9092/jazz/authenticated/identity"); 
     if (_cookie == null) 
     { 
      _cookie = new CookieContainer(); 
     } 
     string a; 
     request.CookieContainer = _cookie; 
     using (var response = request.GetResponse()) 
     { 
      using (StreamReader sr = new StreamReader(response.GetResponseStream())) 
      { 
       a = sr.ReadToEnd(); 
      } 
     } 




     byte[] data = (new ASCIIEncoding()).GetBytes("j_username=myUser&j_password=MyPass"); 

     request = (HttpWebRequest)WebRequest.Create("https://myJazzServer.com:9092/jazz/authenticated/j_security_check"); 

     request.Method = "POST"; 
     request.ContentType = "text/html"; 
     request.ContentLength = data.Length; 
     request.CookieContainer = _cookie; 
     Stream reqStream = request.GetRequestStream(); 
     reqStream.Write(data,0,data.Length); 

     string b; 

     using (var response = request.GetResponse()) 
     { 
      using (var reader = new StreamReader(response.GetResponseStream())) 
      { 
       b = reader.ReadToEnd(); 
      } 
     } 
    } 
+0

你能更具體一點關於什麼是「不工作」?您是否收到異常,響應中沒有內容,響應中有意外的http狀態代碼(例如404,407等)? – Nathan 2010-07-17 17:17:50

+0

@Nathan,它返回一個授權失敗的頁面,我不能給出詳細信息,因爲它返回的是一個名爲authFailed(或類似的東西)的方法的ajax引導程序,所以我無法得到實際的細節。 – 2010-07-17 17:26:09

回答

20

我建議你嘗試以下方法:

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

而且簡化調試你可以通過把它放在你的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> 

這將創建網絡活動的詳細日誌文件,可能會簡化調試。

+0

那麼第一次工作,除了你的產品比我的產品好1000倍之外,我不確定它爲什麼有效,我的產品沒有,但它現在正在工作,那就是重要的。賞金公司22小時:) 非常感謝! – 2010-07-17 18:07:25

+0

如果存在「Set-Cookie」響應,您的實現將錯過它,這可能導致身份驗證失敗。 – PerlDev 2010-08-13 18:59:24

+0

我把這段代碼放到了一個我一直在從一個需要認證的網站獲取資源的小應用中。我必須改變的是POST中發送的數據,它只是起作用。驚奇!現在我需要去弄清楚它是如何工作的,因爲它看起來很神奇! – 2012-05-10 13:05:31

2

這裏是另一種方法,如果你想使用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; 
} 

你可以調用這個函數在你的代碼 -

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) 
{ 
} 

你可以閱讀更多at my blog