• 解决SWFUpload在Chrome、Firefox等浏览器下的问题


    SWFUpload是一个非常不错的异步上传组件,但是在Chrome、Firefox等浏览器下使用的时候会有问题。问题如下:为了防止跳过上传页面直 接向“接受SWFUpload上传的一般处理程序”(假如是Upload.ashx)发送请求造成WebShell漏洞,我的系统中对于 Upload.ashx进行了权限控制,只有登录用户才能进行上传。在IE下没问题,但是在Chrome下运行报错“用户未登录”。

    经过搜索得知:因为SWFUpload是靠Flash进行上传的,Flash在IE下会把当前页面的Cookie发到Upload.ashx,但是Chrome、Firefox下则不会把当前页面的Cookie发到Upload.ashx。因为Session是靠Cookie中保存的SessionId实现的,这样由于当前页面的Cookie不会传递给Flash请求的Upload.ashx,因此请求的文件发送到Upload.ashx就是一个新的Session了,当然这个Session就是没有登录的了。

    解决这个问题的思路也很简单,那就是手动把SessionId传递给服务器,再服务器端读出SessionId再加载Session。其实解决问题的办法 SWFUpload的Demo中已经给出了,那就是在SWFUpload的构造函数中设置post_params参数:

    swfu = new SWFUpload({
                        post_params: {
                            "ASPSESSID": "<%=Session.SessionID %>"
                        }
     
    post_params中设定的键值对将会以Form表单的形式传递到Upload.ashx,也就是SWFUpload提供了为请求增加自定义请求参数的接口。
     
    上面的代码把当前页面的SessionId写到ASPSESSID值中,当用户上传文件后,ASPSESSID就会传递到服务器上了,在Global.asax的Application_BeginRequest中添加如下代码:
                var Request = HttpContext.Current.Request;
                var Response = HttpContext.Current.Response;
     
                try
                {
                    string session_param_name = "ASPSESSID";
                    string session_cookie_name = "ASP.NET_SESSIONID";
     
                    if (HttpContext.Current.Request.Form[session_param_name] != null)
                    {
                        UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
                    }
                    else if (HttpContext.Current.Request.QueryString[session_param_name] != null)
                    {
                        UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString[session_param_name]);
                    }
                }
                catch (Exception)
                {
                    Response.StatusCode = 500;
                    Response.Write("Error Initializing Session");
                }        
                
    其中UpdateCookie方法的定义如下:
            static void UpdateCookie(string cookie_name, string cookie_value)
            {
                HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
                if (cookie == null)
                {
                    cookie = new HttpCookie(cookie_name);
                    //SWFUpload 的Demo中给的代码有问题,需要加上cookie.Expires 设置才可以
                    cookie.Expires = DateTime.Now.AddYears(1);                
                    HttpContext.Current.Request.Cookies.Add(cookie);
                }
                cookie.Value = cookie_value;
                HttpContext.Current.Request.Cookies.Set(cookie);
            }
     

    原理:当用户请求到达ASP.Net引擎的时候Application_BeginRequest方法首先被调用,在方法中看客户端是否提交上来了ASPSESSID,如果有的话则把ASPSESSID的值写入Cookie(以"ASP.NET_SESSIONID"为Key,因为ASP.Net中SessionId就是保存在"ASP.NET_SESSIONID"为Key的Cookie中的),Application_BeginRequest方法后就可以从Cookie中读取到"ASP.NET_SESSIONID"的值还原出页面的Session了。

    如果网站中还用到了Membership的FormsAuthentication验证,则还需要把AUTHID也按照SessionID的方法进行处理,这一点是其他讲到SWFUpload这个Bug处理的文章中没有提到的。

    在SWFUpload的构造函数中设置post_params参数:

    swfu = new SWFUpload({
                        upload_url: "/AdminHT/UploadArticleImg.ashx",
                        post_params: {
                            "ASPSESSID": "<%=Session.SessionID %>",
                            "AUTHID" : "<%=Request.Cookies[FormsAuthentication.FormsCookieName].Value%>"
                        },
     
    在在Global.asax的Application_BeginRequest中添加如下代码:
                try
                {
                    string auth_param_name = "AUTHID";
                    string auth_cookie_name = FormsAuthentication.FormsCookieName;
     
                    if (HttpContext.Current.Request.Form[auth_param_name] != null)
                    {
                        UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
                    }
                    else if (HttpContext.Current.Request.QueryString[auth_param_name] != null)
                    {
                        UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString[auth_param_name]);
                    }
     
                }
                catch (Exception)
                {
                    Response.StatusCode = 500;
                    Response.Write("Error Initializing Forms Authentication");
                }
  • 相关阅读:
    Linux常用命令大全
    C# 多线程、控制线程数提高循环输出效率
    【Redis笔记(四)】 Redis数据结构
    Redis 详解 (一) StackExchange.Redis Client
    C#中的线程(一)入门
    C#多线程
    StackExchange.Redis帮助类解决方案RedisRepository封装(散列Hash类型数据操作)
    【转】C#中使用Redis学习二 在.NET4.5中使用redis hash操作
    使用MongoDB.NET 2.2.4驱动版本对 Mongodb3.3数据库中GridFS增删改查
    .Net-Mongodb学习大全网址
  • 原文地址:https://www.cnblogs.com/zhwl/p/2769440.html
Copyright © 2020-2023  润新知