Authorisation of Website/Media Content in ASP.NET MVC 3

心已入冬 提交于 2019-12-23 04:43:41

问题


I am trying to deny access to a folder or resources when not logged in (prevent leeching). In the folder I have my

Web.config: (/Media)

<?xml version="1.0"?>
<configuration>
  <system.web>
    <authorization>
      <deny users="?"/>
      <allow users="*" />
    </authorization>
  </system.web>
</configuration>

The code I am calling:

Index:

@Video.MediaPlayer(
    path: "~/Media/Tree Felling2.wmv",
    width: "600",
    height: "400",
    autoStart: false,
    playCount: 1,
    uiMode:  "full",
    stretchToFit: true,
    enableContextMenu: true,
    mute: false,
    volume: 75)

@Video.Flash(path: "~/Media/sample.swf",
             width: "80%",
             //height: "600",
             play: true,
             loop: false,
             menu:  true,
             bgColor: "red",
             quality: "medium",
             //scale: "showall",
             windowMode: "transparent")

When logged out: flash is not shown. Media player wont connect to media. ( AS EXPECTED )

When logged in: flash is shown. But media player still wont connect to media.

Where am I going wrong?..


回答1:


Unfortunately this is a known bug with the Windows Media Player for FF. It will work in IE.

The reason for this not working is pretty simple: the plugin doesn't send the authentication cookie along with the request so it is as if you are not authenticated.

The only way to make this work is to append the cookie value as a query string parameter to the request and then resynchronize the session on the server.

Let's put that into action, shall we?

Unfortunately we cannot use the @Video.MediaPlayer helper because it doesn't allow you to specify query string parameters, it works only with physical files (which kinda sucks). So:

<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>

and inside Global.asax we subscribe to the Application_BeginRequest method and resync up the authentication cookie from the request:

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);
}

And that's pretty much it. The only requirement for this to work is to be running in IIS 7 Integrated Pipeline Mode in order for all requests to go through ASP.NET, even those for .wmv files, otherwise the BeginRequest will obviously never trigger for them.

If you are using some legacy web server (such as IIS 6.0) or running in Classic Pipeline mode and don't want to do a wildcard mapping of all requests with ASP.NET you could put all your media files in a secure location (such as ~/App_Data) that cannot be directly accessed by users and then serve them through a controller action decorated with the [Authorize] attribute:

[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");
}

and then:

<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>


来源:https://stackoverflow.com/questions/11966958/authorisation-of-website-media-content-in-asp-net-mvc-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!