使用SSO身份验证使用REST服务

时间:2015-09-04 05:42:59

标签: javascript web-services wcf rest authentication

我从中使用服务器(https://example.com/zzzzzz/rest/services/

如果我只是将其粘贴到Chrome中,系统会提示我进行身份验证。我把我已知的凭据和他们放在我身边。

但是,如果我尝试访问类似的内容:

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

在带有XMLHttpRequest的Javascript中,我每次都收到401 Unauthorized响应。如果我使用我的凭据为此请求添加标题,则它可以工作:

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

但是,这意味着在每个JS代码中公开该用户名和密码,并为每个XMLHttpRequest添加一个标头(此时我无法做到)。 上面的服务器不是我的,所以除了在登录后使用服务以外我无能为力。

当我尝试访问这些服务时,有没有办法让我自己的服务器(IIS)来处理这种身份验证?

额外信息:这是ArcGIS服务器的全部内容。

1 个答案:

答案 0 :(得分: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;
}