2015-09-04 6 views
1

Существует сервер, с которого я потребляю веб-служб (https://example.com/zzzzzz/rest/services/)Потребляя REST службы с проверкой подлинности 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

Здравствуйте, спасибо, что ответ! Однако кажется, что в конце он все еще устанавливает заголовок запроса и hardcodes имя пользователя/пароль (в base64). Я думаю, мне, возможно, придется каким-то образом создать прокси-сервер, который пересылает запросы и возвращает результаты, но также обрабатывает аутентификацию для меня. Однако я не совсем уверен, как это сделать ... –

ответ

1

Я нашел решение. Идея состоит в том, чтобы создать веб-сервис (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; 
} 
Смежные вопросы