博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
解决SWFUpload在Chrome、Firefox等浏览器下的问题
阅读量:5048 次
发布时间:2019-06-12

本文共 4952 字,大约阅读时间需要 16 分钟。

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({
// Backend Settings upload_url: "/Upload.ashx", 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; /* Fix for the Flash Player Cookie bug in Non-IE browsers.              * Since Flash Player always sends the IE cookies even in FireFox              * we have to bypass the cookies by sending the values as part of the POST or GET              * and overwrite the cookies with the passed in values.              *              * The theory is that at this point (BeginRequest) the cookies have not been read by              * the Session and Authentication logic and if we update the cookies here we'll get our              * Session and Authentication restored correctly */ 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({
// Backend Settings 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"); }

如鹏网正在报名,有网络的地方就可以参加如鹏网的学习,学完就能高薪就业,

 

    三年前只要懂“三层架构”就可以说“精通分层架构”;现在则需要懂IOC(AutoFac等)、CodeFirst、lambda、DTO等才值钱;

    三年前只要会SQLServer就可以说自己“精通数据库开发”;现在则需还需要掌握MySQL等开源数据库才能说是“.Net开源”时代的程序员;

    三年前只要会进行用户上传内容的安全性处理即可;现在则需要熟悉云存储、CDN等才能在云计算时代游刃有余;

    三年前只要掌握Lucene.Net就会说自己“熟悉站内搜索引擎开发”;现在大家都用ElasticSearch了,你还用Lucene.Net就太老土了;

    三年前发邮件还是用SmtpClient;现在做大型网站发邮件必须用云邮件引擎;

    三年前缓存就是Context.Cache;现在则是Redis、Memcached的天下;

    如鹏网再次引领.Net社区技术潮流!

转载于:https://www.cnblogs.com/rupeng/archive/2012/01/30/2332427.html

你可能感兴趣的文章
JAVA常用设计模式整理
查看>>
this详解与面向对象编程
查看>>
谈谈 C++ 中的右值引用
查看>>
树状数组之二维树状数组
查看>>
使用.NET身份验证防止不登录直接访问页面 .
查看>>
九度OJ 1156:谁是你的潜在朋友
查看>>
用户子查询,用case
查看>>
数组与集合List的相互转化
查看>>
Android—基于Socket与上传图片到客户端
查看>>
Docker安装MySQL并配置my.cnf
查看>>
ASSERT_VALID(pDoc)分析
查看>>
Java提高篇——equals()与hashCode()方法详解
查看>>
表单中用户输入"&lt"等转义字符,保存后数据库是原文保存的,但是查看的时候显示的是"<",如何是的&lt;字符在网页原样显示出来。...
查看>>
宗溯软件聚焦2012伦敦奥运会
查看>>
5 python字典dict的操作
查看>>
synchronized的实现原理及锁优化
查看>>
JMeter入门(2):一个简单实例
查看>>
夺命雷公狗---Smarty NO:17 html_table函数
查看>>
Yaf入门笔记
查看>>
基于int的Linux的经典系统调用实现
查看>>