【发布时间】:2014-09-16 17:14:34
【问题描述】:
我需要能够支持 MVC (4) 网站上的“辅助”内容——图像、PDF、视频等。这些内容大部分是由使用该网站的客户提供的,因此应该无法访问对未经身份验证的用户。
(我们正在使用表单身份验证来生成身份验证票证。请注意,我们不一定必须使用内置的成员资格/身份提供程序,因为我们的一些客户希望通过其他方式进行身份验证表示例如联合身份服务。)
如here 所述,我已通过将站点设置为通过 ASP.NET(通过 runAllManagedModulesForAllRequests)路由/授权所有请求来保护静态内容。
我发现我需要允许匿名访问 Content 和 Scripts 文件夹(通过 location)......但这种配置适用于大多数内容类型。
但它不适用于视频内容,尤其是在 Internet Explorer 中。媒体播放器出现,但报告它无法播放文件。 “播放器可能不支持用于创建文件的文件类型或编码。”
(有趣的是,Chrome 或 Firefox 中没有错误。视频在新标签页中播放。)
我很确定问题出在媒体播放器上。如果我添加一个location 元素并允许匿名访问视频,它就可以正常播放。我们过去也遇到过类似的问题,根本原因最终被证明与安全/身份验证相关。
但显然我无法更改媒体播放器。而且我必须支持IE。那么......有没有人知道在 ASP.NET MVC 中以编程方式解决这个问题的方法?任何帮助将不胜感激。
我似乎记得看到过一篇关于发送身份验证信息的帖子,而不仅仅是通过 HTTP 请求。我现在找不到那个帖子。但根据 Fiddler 的说法,请求实际上是一个 HTTP GET。而且我们不会发送身份验证标头,而是发送身份验证 cookie。
更新:
我想我可以将答案改写为this question。
它涉及将标志和授权 cookie 值附加到内容 URL,并连接到 Application_BeginRequest 事件。
在视图中:
var asset = ...;
var authToken = Request.Cookies[FormsAuthentication.FormsCookieName].Value;
var assetUri = string.Format("~/Media/{0}?requireAuthSync=true&token={1}",
asset.ID, Url.Encode(authToken));
然后在Global.asax.cs:
protected void Application_BeginRequest()
{
if (!string.IsNullOrEmpty(Context.Request["requireAuthSync"]))
{
AuthCookieSync();
}
}
private void AuthCookieSync()
{
var authParamName = "token";
var authCookieName = FormsAuthentication.FormsCookieName;
try
{
if (!string.IsNullOrEmpty(Context.Request[authParamName]))
{
var authCookieValue = Context.Request.QueryString[authParamName];
var authCookie = Context.Request.Cookies.Get(authCookieName)
?? new HttpCookie(authCookieName);
authCookie.Value = authCookieValue;
Context.Request.Cookies.Set(authCookie);
}
}
catch
{
}
}
使用这种方法,视频实际上可以在 IE 中播放。
但是,现在可以为视频(或其他内容)添加书签并使用书签访问内容而无需经过身份验证......因此网站的安全性实际上被破坏了。
看来,为了保护网站安全,如果 cookie 不存在,我不应该创建它。但是对于媒体播放器,创建 cookie 是播放视频的唯一方法。我似乎被困在 Catch-22 中。
任何见解将不胜感激。
【问题讨论】:
标签: asp.net-mvc asp.net-mvc-4 video forms-authentication