【问题标题】:Is it possible to share ASP.NET session cookies between IE and word add-on是否可以在 IE 和 word 插件之间共享 ASP.NET 会话 cookie
【发布时间】:2009-10-16 15:53:31
【问题描述】:

我有一个要求,允许用户从网页打开 Word 文档并使用 MS Word 应用程序在本地进行编辑。最后他们应该能够(回发)将修改后的文档保存到服务器。

针对上述要求,我选择了 ASP.NET、C#、.NET 3.5、IIS、IE6(或更高版本)和 MS Office 2007(应该在所有工作站中)。

我开发了一个 ASP.NET Web 应用程序,它具有三个 aspx 页面 Login.aspx、DocList.aspx 和 SaveDoc.aspx。

  1. Lo​​gin.aspx - 身份验证/授权。 (认证类型:表单)
  2. DocList.aspx - 显示/下载 word 文档。
  3. SaveDoc.aspx - 将修改后的word文档保存在服务器中。

我还开发了一个共享单词功能区加载项,它可以帮助用户通过单击加载项中的“发布”按钮将修改后的文档保存到服务器。已使用 Web 客户端上传修改后的文档。为了将修改后的文档保存到服务器,所有工作站都应该安装这个插件。

    string modifiedWordXml = applicationObject.ActiveDocument.WordOpenXML;

    WebClient client = new WebClient();
    string serverAddress = "http://localhost:51507/DOCMGR/SaveDoc.aspx";
    byte[] byteArray = Encoding.UTF8.GetBytes(modifiedWordXml);
    byte[] responceArray = client.UploadData(serverAddress, byteArray);
    string res = Encoding.UTF8.GetString(responceArray);
    MessageBox.Show(res,"Document Manager");

网页正在显示 Word 文档链接列表,单击该链接后,Word 文档将在客户端的单独 MS Word 应用程序中打开。在那里,用户可以编辑文档,点击加载项功能区上的“发布”按钮,修改后的文档成功保存到服务器。

我的要求得到满足,禁用身份验证后一切正常。

如果我启用了身份验证,加载项无法将修改后的文档上传到服务器,因为它没有经过身份验证并且无法从 IE 共享身份验证 cookie。

是否有任何解决方法/解决方案可以满足我的要求?您的帮助将不胜感激。

【问题讨论】:

    标签: c# asp.net session ms-word webclient


    【解决方案1】:

    您可以 PInvoke GetInternetCookie 以获取 ASPNET 会话 cookie。

            [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
        protected static extern bool InternetGetCookie(
            string url,
            string name,
            StringBuilder cookieData,
            ref int length);
    

    然后您可以手动构建一个 HttpWebRequest 并将 ASPNET 会话 cookie 添加到您的请求对象上的 CookieContainer 中。可能有一种方法可以将 cookie 添加到由 WebClient 创建的底层 WebRequest,如果是这样,您可以使用它。

    希望这会有所帮助。

    编辑:

    基本上这里是我在 HttpWebRequest 上使用的代码,用于在 IE cookie 缓存中设置 cookie。不幸的是,我没有任何代码可以在此处读取缓存中的 cookie。

    基本上,您想要做的是对该代码进行一些派生,并使用 InteretGetCookie 使用您网站域中的 cookie 创建您的 CookieCollection 对象。您必须手动解析这些。然后在您的 HttpWebRequest 上,您可以使用 InternetGetCookie 从您的域中读取的 cookie,并将它们传递到您创建的 CookieContainer 中。

    public class HttpWebConnection
    {
        [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
        protected static extern bool InternetSetCookie(
            string url,
            string name,
            string cookieData);
    
        [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
        protected static extern bool InternetGetCookie(
            string url,
            string name,
            StringBuilder cookieData,
            ref int length);
    
        public HttpWebConnection()
        {
            Cookies = new CookieContainer();
            AutoRedirect = false;
        }
    
        public HttpWebConnection(string baseAddress)
            : this()
        {
            BaseAddress = baseAddress;
            BaseUri = new Uri(BaseAddress);
        }
    
        public bool AutoRedirect { get; set; }
    
        public Uri BaseUri { get; private set; }
    
        public string BaseAddress { get; private set; }
    
        public CookieContainer Cookies { get; private set; }
    
        public virtual HttpWebResponse Send(string method, Uri uri)
        {
            return Send(method, uri, null, false);
        }
    
        public virtual HttpWebResponse Send(string method, Uri uri, string post, bool authenticating)
        {
            Uri absoluteUri = null;
            if (uri.IsAbsoluteUri)
            {
                absoluteUri = uri;
            }
            else
            {
                absoluteUri = new Uri(BaseUri, uri);
            }
    
            HttpWebRequest request = WebRequest.Create(absoluteUri) as HttpWebRequest;
            request.CookieContainer = Cookies;
            request.Method = method;
            if (method == "POST")
            {
                request.ContentType = "application/x-www-form-urlencoded";
            }
    
            request.AllowAutoRedirect = false;
    
            if (!string.IsNullOrEmpty(post))
            {
                Stream requestStream = request.GetRequestStream();
                byte[] buffer = Encoding.UTF8.GetBytes(post);
                requestStream.Write(buffer, 0, buffer.Length);
                requestStream.Close();
            }
    
            HttpWebResponse response = null;
    
            response = request.GetResponse() as HttpWebResponse;
    
            foreach (Cookie cookie in response.Cookies)
            {
                bool result = InternetSetCookie(BaseAddress, cookie.Name, cookie.Value);
                if (!result)
                {
                    int errorNumber = Marshal.GetLastWin32Error();
                }
            }
    
            if (AutoRedirect && (response.StatusCode == HttpStatusCode.SeeOther
                        || response.StatusCode == HttpStatusCode.RedirectMethod
                        || response.StatusCode == HttpStatusCode.RedirectKeepVerb
                        || response.StatusCode == HttpStatusCode.Redirect
                        || response.StatusCode == HttpStatusCode.Moved
                        || response.StatusCode == HttpStatusCode.MovedPermanently))
            {
                string uriString = response.Headers[HttpResponseHeader.Location];
                Uri locationUri;
                //TODO investigate if there is a better way to detect for a relative vs. absolute uri.
                if (uriString.StartsWith("HTTP", StringComparison.OrdinalIgnoreCase))
                {
                    locationUri = new Uri(uriString);
                }
                else
                {
                    locationUri = new Uri(this.BaseUri, new Uri(uriString));
                }
    
                response = Send("GET", locationUri);
            }
    
            return response;
        }
    }
    

    【讨论】:

    • 感谢您的帮助。我已将代码更改为使用 HttpWebRequest 而不是 WebClient,并将 ASPNET 会话 cookie 添加到请求对象的 CookieContainer 中。仍然没有运气。我附上下面的代码供您参考。如果我遗漏了什么,请告诉我。 HttpWebRequest 请求 = (HttpWebRequest)WebRequest.Create("SERVERIP/DOCMGR/SaveDoc.aspx"); Uri uri = new Uri("SERVERIP"); request.CookieContainer = GetUriCookieContainer(uri); request.Method = "POST";注意:HTTP:// 在这篇文章中被删除了
    • 我阅读了一篇 msdn 文章,其中说“InternetGetCookie 不会返回服务器在 Set-Cookie 标头中使用“HttpOnly”属性标记为不可编写脚本的 cookie。” MSDN URL:msdn.microsoft.com/en-us/library/aa384710%28VS.85%29.aspx 由于我们使用表单身份验证并且 cookie 默认具有“HttpOnly”属性,因此 InternetGetCookie 不返回 cookie。有什么解决方法/解决方案吗?提前致谢。
    • 这是一个愚蠢的问题,但是当用户通过身份验证且未标记为 HttpOnly 时,您能否只在您的站点上创建一个 cookie 用于身份验证?然后,您可以查找在用户通过身份验证后创建的自己的会话 cookie,而不是查找 .NET 会话 cookie?
    • 我找到了我的问题的答案。我在 FormsAuthentication.RedirectFromLoginPage 之后为表单身份验证 cookie 设置了 HttpOnly false。它与 .NET 会话 cookie 配合使用很酷。无论如何,谢谢你。 FormsAuthentication.RedirectFromLoginPage(userName.Text,true); foreach(Response.Cookies.AllKeys 中的字符串 s){ if (s == System.Web.Security.FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid") { Response.Cookies[s].HttpOnly =假; } }
    • 没问题,很高兴能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多