2015-09-04 84 views
1

消費REST服務有一個從我使用Web服務(https://example.com/zzzzzz/rest/services/與SSO認證

如果我只是粘貼在Chrome中,我提示進行身份驗證的服務器。我把我已知的證書和他們,我可以自由地漫遊。

但是,如果我嘗試訪問是這樣的:

https://example.com/zzzzzz/rest/services/tttttt/uuuuuu/MapServer

在Javascript中使用XMLHttpRequest,我得到一個401未授權的響應每一次。它的工作原理,如果我添加頁眉這一要求與我的憑據:

xml_req.setRequestHeader("Authorization", "Basic " + btoa("username:password"); 

然而,這將意味着暴露在每一個JS代碼,用戶名和密碼,也是一個頭添加到每個XMLHttpRequest的(這是我不能做的這點)。 上面的服務器不是我的,所以除登錄後使用服務之外,我無能爲力。

當我嘗試訪問這些服務時,是否有辦法讓我自己的服務器(IIS)爲我處理此身份驗證?

額外信息:這是所有的ArcGIS服務器。

+0

這可以幫助你,HTTP: //chrisroos.co.uk/blog/2013-03-08-the-behaviour-of-xmlhttprequest-withcredentials-when-used-with-cors – cracker

+0

你好,感謝您的回覆!然而,最後他似乎仍然設置了請求頭並且硬編碼了用戶名/密碼(在base64中)。 我想我可能不得不做一個代理服務器,轉發請求並返回結果,但也爲我處理身份驗證。不過,我不確定如何做到這一點...... –

回答

1

我找到了解決方案。 這個想法是創建一個web服務(在我的情況下是ashx),它獲取請求的服務作爲參數代理(myproxy.com?https://websitetobeproxied.com/serviceToBeProxied),並將其連同憑證一起發送到代理服務器(使用網絡憑證)結果並將其發送回客戶端。

這將是其憑據傳遞HTTP請求的功能:

private System.Net.WebResponse doHTTPRequest(string uri, byte[] bytes, string method, string contentType, ServerUrl serverUrl) { 

    System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(uri); 
    req.ServicePoint.Expect100Continue = false; 


    // Add credentials 
    req.Credentials = new NetworkCredential("username", "password"); 

    //For testing I automatically validate any ssl certificates. You may want to disable this in production 
    req.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { 
     return true; 
    }; 

    //Get the request method ("GET", "SET" etc.) 
    req.Method = method; 

    if (bytes != null && bytes.Length > 0 || method == "POST") { 
     req.Method = "POST"; 
     req.ContentType = string.IsNullOrEmpty(contentType) ? "application/x-www-form-urlencoded" : contentType; 
     if (bytes != null && bytes.Length > 0) 
      req.ContentLength = bytes.Length; 
     using (Stream outputStream = req.GetRequestStream()) { 
      outputStream.Write(bytes, 0, bytes.Length); 
     } 
    } 
    return req.GetResponse(); 
} 

,這將是獲取並將結果發送回法:

private bool fetchAndPassBackToClient(System.Net.WebResponse serverResponse, HttpResponse clientResponse, bool ignoreAuthenticationErrors) 
{ 
    if (serverResponse != null) 
    { 
     clientResponse.ContentType = serverResponse.ContentType; 
     using (Stream byteStream = serverResponse.GetResponseStream()) 
     { 
      // Text 
      if (serverResponse.ContentType.Contains("text") || 
       serverResponse.ContentType.Contains("json") || 
       serverResponse.ContentType.Contains("xml")) 
      { 
       using (StreamReader sr = new StreamReader(byteStream)) 
       { 
        string strResponse = sr.ReadToEnd(); 
        if (
         !ignoreAuthenticationErrors 
         && strResponse.IndexOf("{\"error\":{") > -1 
         && (strResponse.IndexOf("\"code\":498") > -1 || strResponse.IndexOf("\"code\":499") > -1) 
        ) 
         return true; 
        clientResponse.Write(strResponse); 
       } 
      } 
      else 
      { 
       // Binary response (Image or other binary) 
       // Don't cache the result 
       clientResponse.CacheControl = "no-cache"; 
       byte[] buffer = new byte[32768]; 
       int read; 
       while ((read = byteStream.Read(buffer, 0, buffer.Length)) > 0) 
       { 
        clientResponse.OutputStream.Write(buffer, 0, read); 
       } 
       clientResponse.OutputStream.Close(); 
      } 
      serverResponse.Close(); 
     } 
    } 
    return false; 
}