使用 ASP.NET MVC 上传(会话和身份验证)
Posted
技术标签:
【中文标题】使用 ASP.NET MVC 上传(会话和身份验证)【英文标题】:Uploadify (Session and authentication) with ASP.NET MVC 【发布时间】:2010-12-16 07:07:01 【问题描述】:当我对 uplodify (http://www.uploadify.com/) 使用的操作或控制器使用授权过滤器时,无法执行操作...
而且 Session 没有被检索到。
我发现这是检索到的用户会话:
http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx
但是如何将它与[Authorize]
过滤器和检索到的会话一起使用?
【问题讨论】:
本网站用于问答。可以回答您自己的问题或将知识库类型的文章放在这里,但以问题的形式表达它们,然后在答案中用您的解决方案来回答它们。 MVC中不能使用AuthorizeAttribute和Session状态?你确定吗? Sosh,是我写的吗?? 【参考方案1】:为了纠正这个问题,我建议你一个解决方案...使用 uploadify 发送 auth cookie 值和 session id cookie 值,并在检索会话之前重新创建它。
这是要在视图中实现的代码:
<script>
var auth = "<% = Request.Cookies[FormsAuthentication.FormsCookieName]==null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>";
var ASPSESSID = "<%= Session.SessionID %>";
$("#uploadifyLogo").uploadify(
...
formData: ASPSESSID: ASPSESSID, AUTHID: auth
);
然后在 Global.asax 中:
protected void Application_BeginRequest(object sender, EventArgs e)
/* we guess at this point session is not already retrieved by application so we recreate cookie with the session id... */
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
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
private void UpdateCookie(string cookie_name, string cookie_value)
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
if (null == cookie)
cookie = new HttpCookie(cookie_name);
cookie.Value = cookie_value;
HttpContext.Current.Request.Cookies.Set(cookie);
瞧,用这种方法它是完全透明的。
希望对你有所帮助!! ;)
已编辑:使用 formData 而不是 scriptData
【讨论】:
确实,这非常有帮助:感谢您。我认为问题必须涉及 Flash 检索会话 cookie 的方式(如果有的话),但我只是不知道到底发生了什么,直到我看到这个我才意识到你实际上可以更新传入的 cookie这种方式。你是戈拉姆英雄,谢谢。 =) 将 sessionId 放入脚本中是个坏主意,因为它容易受到会话劫持(除非您通过 SSL 提供脚本)。 @Adam Nofsinger - 这是真的,但不需要更多地敞开心扉。使用 cookie,您可以将它们设置为 HTTPOnly(我知道不是完整的证明),但使用脚本可以将自己打开到恶意 js。这是一个类似的响应 - 不需要会话 ID 在您的 js 中。 ***.com/questions/4538174/… 对不起,我不是要挑剔,你的答案很好(帮了我),但我最近做了一些安全研究,引起了我的注意。 +1000 真的帮助了我。 -999 有 two 空catch
子句。伤了我的眼睛...
对于较新版本的 Uploadify,使用 formData 而不是 scriptData【参考方案2】:
对于VB转换的代码 *以 开始代码块
即
var auth='<%# IIf(Request.Cookies(FormsAuthentication.FormsCookieName) Is Nothing, "",
Request.Cookies(FormsAuthentication.FormsCookieName).Value)%>';
var ASPSESSID = '<%# Session.SessionID%>';
【讨论】:
【参考方案3】:此解决方案效果很好。如果有人需要,我将代码翻译成 vb:
Protected Sub Application_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs)
'we guess at this point session is not already retrieved by application so we recreate cookie with the session id...
Try
Dim session_param_name = "ASPSESSID"
Dim session_cookie_name = "ASP.NET_SessionId"
If Not HttpContext.Current.Request.Form(session_param_name) Is Nothing Then
UpdateCookie(session_cookie_name, HttpContext.Current.Request.Form(session_param_name))
ElseIf Not HttpContext.Current.Request.QueryString(session_param_name) Is Nothing Then
UpdateCookie(session_cookie_name, HttpContext.Current.Request.QueryString(session_param_name))
End If
Catch ex As Exception
End Try
Try
Dim auth_param_name = "AUTHID"
Dim auth_cookie_name = FormsAuthentication.FormsCookieName
If Not HttpContext.Current.Request.Form(auth_param_name) Is Nothing Then
UpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form(auth_param_name))
ElseIf Not HttpContext.Current.Request.QueryString(auth_param_name) Is Nothing Then
UpdateCookie(auth_cookie_name, HttpContext.Current.Request.QueryString(auth_param_name))
End If
catch ex As Exception
End Try
End Sub
Private Sub UpdateCookie(ByVal cookie_name As String, ByVal cookie_value As String)
Dim cookie = HttpContext.Current.Request.Cookies.Get(cookie_name)
If cookie Is Nothing Then
cookie = New HttpCookie(cookie_name)
End If
cookie.Value = cookie_value
HttpContext.Current.Request.Cookies.Set(cookie)
End Sub
这是 javascript 变量赋值的部分:
var auth = "<%=IIf(Request.Cookies(FormsAuthentication.FormsCookieName) Is Nothing, "", Request.Cookies(FormsAuthentication.FormsCookieName).Value)%>";
var ASPSESSID = "<%=Session.SessionID%>";
也许在 VB 工作的人可以从中受益。
【讨论】:
以上是关于使用 ASP.NET MVC 上传(会话和身份验证)的主要内容,如果未能解决你的问题,请参考以下文章
使用 WIF 和 jquery ajax 请求时 ASP.NET MVC 3 中的会话 Cookie 过期处理