斗士狗 2013-10-31 17:28 采纳率: 0%
浏览 27

Ajax呼叫传递安全性

I am trying to make an ajax call (using IE 10) to a page that returns json (not jsonp) but I keep getting a "401 - Unauthorized: Access is denied due to invalid credentials." The site is setup in IIS to use "Windows Authentication", however, if I change the site to enable Anonymous Authentication the call works. Below is the code I am using to make the call. What am I missing with my call or what do I need to change on my webserver? The Windows Authentication is currently set up to use NTLM authentication on the Windows Auth.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="scripts/jquery-2.0.3.min.js"></script>
    <script src="scripts/base64.js"></script>
    <script type="text/javascript">
        function QueryMyData() {
            var postUrl = 'http://mydevpage/storage.ashx';
            var data = 'AssetNumber=102405';
            $.support.cors = true;
            $.ajax({
                type: "POST",
                url: postUrl,
                data: data,
                dataType: 'json',
                crossDomain: true,
                cache: false,
                username: "mydomain.net\\myuser",
                password: "password",
                beforeSend: function (xhr) {
                    xhr.withCredentials = true;

                },
                success: function (result) {
                    if (result) {
                        if (result.error)
                            alert(result.error);
                        else
                            alert(result.id);
                    }
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert('Unknow Error:' + thrownError + ajaxOptions + xhr.status + " " + xhr.statusText);
                }
            });
        }
        QueryMyData();
    </script>
</head>
<body>
</body>
</html>
  • 写回答

1条回答 默认 最新

  • weixin_33724059 2013-11-04 16:56
    关注

    I found a solution to my problem. While I was not ever able to get the ajax request to work with security hitting a page on another domain, I did find a way to accomplish this. I ended up creating a ProxyHandler.ashx page and setting the permission on the request using the WebClient.

    html page

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
        <script type="text/javascript">
            function QueryMyData() {
                var postUrl = './ProxyHandler.ashx?http://mydevpage/storage.ashx';
                var data = 'AssetNumber=102405';
                $.support.cors = true;
                $.ajax({
                    type: "POST",
                    url: postUrl,
                    data: data,
                    dataType: 'json',
                    cache: false,
                    success: function (result) {
                        if (result) {
                            if (result.error)
                                alert(result.error);
                            else
                                alert(result.id);
                        }
                    },
                    error: function (xhr, ajaxOptions, thrownError) {
                        alert('Unknow Error:' + thrownError + ajaxOptions + xhr.status + " " + xhr.statusText);
                    }
                });
            }
            QueryMyData();
        </script>
    </head>
    <body>
    </body>
    </html>
    

    Here is the proxy page (ProxyHandler.ashx)

    public class ProxyHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            string username = "svcMyServiceAccount";
            string password = "password";
            try
            {
                string uri = context.Request.RawUrl.Substring(context.Request.RawUrl.IndexOf("?") + 1);
    
                if (uri.StartsWith("ping"))
                {
                    context.Response.Write("<html><body>Hello ProxyHandler</body></html>");
                    return;
                }
    
                context.Response.ContentType = "text/plain";
    
                byte[] bytes = new byte[context.Request.InputStream.Length];
                context.Request.InputStream.Read(bytes, 0, (int)context.Request.InputStream.Length);
                var data = System.Text.Encoding.UTF8.GetString(bytes);
    
                using (System.Net.WebClient wc = new System.Net.WebClient())
                {
                    wc.Headers["Content-Type"] = "application/x-www-form-urlencoded";
                    //this is the magic of getting auth passed.  See post http://stackoverflow.com/questions/1680718/domain-credentials-for-a-webclient-class-dont-work
                    wc.Credentials = CreateCredientialCached(uri, username, password, "mydomain");
                    var response = wc.UploadString(new Uri(uri, UriKind.Absolute), "POST", data);
                    context.Response.Write(response); //already in the JSON Reponse class format
                }
            }
            catch (Exception e)
            {
                context.Response.Write(GetJSON(string.Empty, e));
            }
        }
    
        private CredentialCache CreateCredientialCached(string uri, string userName, string userPassword, string domain)
        {
            CredentialCache cc = new CredentialCache();
            cc.Add(new Uri(uri), "NTLM", new NetworkCredential(userName, userPassword, domain));
            return cc;
        }
    
        private string GetJSON(string id, Exception error)
        {
            var json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(new Response() { id = id, error = error != null ? error.ToString() : string.Empty });
            return json;
        }
    
        // Necessary for IHttpHandler implementation
        public bool IsReusable
        {
            get { return false; }
        }
    
        private class Response
        {
            public string id { get; set; }
            public string error { get; set; }
        };
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题