2015-09-04 1 views
1

Il y a un serveur à partir duquel j'utiliser les services Web (https://example.com/zzzzzz/rest/services/)Consommant service REST avec l'authentification SSO

Si je colle tout cela dans Chrome, je suis invité à vous authentifier. Je mets mes références connues et je suis libre de me promener.

Cependant, si je tente d'accéder à quelque chose comme:

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

en Javascript avec XMLHttpRequest, je reçois une réponse 401 non autorisée chaque fois. Il fonctionne si j'ajoute un en-tête à cette demande avec mes lettres de créance:

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

Cependant, cela signifierait pour exposer ce nom d'utilisateur et mot de passe dans tous les codes JS et également ajouter un en-tête à chaque XMLHttpRequest (que je ne peux pas faire à ce point). Le serveur ci-dessus n'est pas le mien, donc je ne peux rien faire d'autre que consommer des services après que je me connecte.

Est-ce que je peux obtenir mon propre serveur (IIS) pour gérer cette authentification pour moi chaque fois que j'essaie d'accéder à ces services?

Informations supplémentaires: Tout est pour un serveur ArcGIS.

+0

Cela pourrait vous aider, http: //chrisroos.co.uk/blog/2013-03-08-the-behaviour-of-xmlhttprequest-withcredentials-when-used-with-cors – cracker

+0

Bonjour, merci pour la réponse! Cependant, il semble qu'à la fin il définit toujours l'en-tête de la requête et code le nom d'utilisateur/mot de passe (en base64). Je pense que je devrais faire en quelque sorte un serveur proxy qui transmet les demandes et renvoie les résultats, mais gère également l'authentification pour moi. Cependant, je ne suis pas sûr de savoir comment faire ça ... –

Répondre

1

J'ai trouvé la solution. L'idée est de créer un webservice (ashx dans mon cas) qui reçoit le service demandé comme paramètre (myproxy.com? https://websitetobeproxied.com/serviceToBeProxied), l'envoie au serveur mandataire avec les informations d'identification (en utilisant les informations d'identification réseau), récupère le résultat et le renvoie au client.

Ce serait la fonction de requête HTTP qui passe les informations d'identification:

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

Et ce serait la méthode pour récupérer et renvoyer le résultat:

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