不幸的是,这是适用于 FF 的 Windows Media Player 的一个已知错误。它将在 IE 中工作。
这不起作用的原因很简单:插件不会将身份验证 cookie 与请求一起发送,所以就好像您没有经过身份验证一样。
完成这项工作的唯一方法是将 cookie 值作为查询字符串参数附加到请求中,然后在服务器上重新同步会话。
让我们付诸行动,好吗?
不幸的是,我们不能使用@Video.MediaPlayer
帮助程序,因为它不允许您指定查询字符串参数,它仅适用于物理文件(这有点糟糕)。所以:
<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6" height="400" width="600" >
<param name="URL" value="@Url.Content("~/media/test.wmv?requireAuthSync=true&token=" + Url.Encode(Request.Cookies[FormsAuthentication.FormsCookieName].Value))" />
<param name="autoStart" value="False" />
<param name="uiMode" value="full" />
<param name="stretchToFit" value="True" />
<param name="volume" value="75" />
<embed src="@Url.Content("~/media/test.wmv?requireAuthSync=true&token=" + Url.Encode(Request.Cookies[FormsAuthentication.FormsCookieName].Value))" width="600" height="400" type="application/x-mplayer2" autoStart="False" uiMode="full" stretchToFit="True" volume="75" />
</object>
在里面Global.asax
我们订阅该Application_BeginRequest
方法并从请求中重新同步身份验证cookie:
protected void Application_BeginRequest()
{
if (!string.IsNullOrEmpty(Context.Request["RequireAuthSync"]))
{
AuthCookieSync();
}
}
private void AuthCookieSync()
{
try
{
string authParamName = "token";
string authCookieName = FormsAuthentication.FormsCookieName;
if (!string.IsNullOrEmpty(Context.Request[authParamName]))
{
UpdateCookie(authCookieName, Context.Request.QueryString[authParamName]);
}
}
catch { }
}
private void UpdateCookie(string cookieName, string cookieValue)
{
var cookie = Context.Request.Cookies.Get(cookieName);
if (cookie == null)
{
cookie = new HttpCookie(cookieName);
}
cookie.Value = cookieValue;
Context.Request.Cookies.Set(cookie);
}
差不多就是这样。这个工作的唯一要求是在 IIS 7 集成管道模式下运行,以便所有请求都通过 ASP.NET,即使是.wmv
文件请求,否则BeginRequest
显然永远不会触发它们。
如果您使用一些旧版 Web 服务器(例如 IIS 6.0)或在经典管道模式下运行,并且不想使用 ASP.NET 对所有请求进行通配符映射,您可以将所有媒体文件放在安全位置(例如as ~/App_Data
) 不能被用户直接访问,然后通过使用[Authorize]
属性修饰的控制器操作为他们提供服务:
[Authorize]
public ActionResult Media(string file)
{
var appData = Server.MapPath("~/App_Data");
var filename = Path.Combine(path, file);
filename = Path.GetFullPath(filename);
if (!filename.StartsWith(appData))
{
// prevent people from reading arbitrary files from your server
throw new HttpException(403, "Forbidden");
}
return File(filename, "application/octet-stream");
}
进而:
<object classid="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6" height="400" width="600" >
<param name="URL" value="@Url.Action("media", "home", new { requireAuthSync = true, token = Request.Cookies[FormsAuthentication.FormsCookieName].Value })" />
<param name="autoStart" value="False" />
<param name="uiMode" value="full" />
<param name="stretchToFit" value="True" />
<param name="volume" value="75" />
<embed src="@Url.Action("media", "home", new { requireAuthSync = true, token = Request.Cookies[FormsAuthentication.FormsCookieName].Value })" width="600" height="400" type="application/x-mplayer2" autoStart="False" uiMode="full" stretchToFit="True" volume="75" />
</object>