One of the useful benefits of IIS 7.0 and the ASP.NET Integrated mode is the ability to protect all content using ASP.NET Forms Authentication. 

In the past, people would often protect the application pages themselves, and leave images and media content open for public access.  It wasn’t easy to extend the same internet-based authentication scheme to static content unless the static content was served through custom handlers.  Even this wasn’t a perfect solution as you’d often lose performance and static content features such as static compression and ranged request support.

With IIS 7.0, you can configure Forms Authentication and Url Authorization rules once for the entire site, and rest easy knowing that your ASPX pages, PHP scripts, HTML files and media content is protected from unauthorized access.

Unfortunately, if you are serving web video using embedded video players, you may see that your embedded player becomes broken when using forms authentication.  E.g. an embedded Windows Media Player may yeild this:

Embedded Windows Media Player fails when Forms Authentication is enabled 

Why does this happen?

Here is why.  When you log in to your site using Forms Authentication, you are typically issued a cookie that contains your authentication ticket.  On subsequent requests, the browser sends this cookie and the server automatically authenticates you.

When the embedded media player makes a request to retrieve the media content, it automatically forwards the browser cookies for that domain. This should ensure that the server can authenticate the media player’s request and return the media file.

Unfortunately, this does not happen for Forms Authentication. 

This is because when we developed ASP.NET 2.0, we made a decision to mark the Forms Authentication cookie with the HttpOnly attribute.  This attribute prevents script from being able to access the cookie – thereby blocking potential Cross-Site Scripting (XSS) attacks aimed at stealing the authentication cookie.

Because of this security measure, the embedded media player does not have access to the Forms Authentication cookie, and is unable to retrieve the media content if it is protected by Forms Authentication.

To workaround, we can remove the HttpOnly attribute from Forms Authentication cookies when they are issued.

WARNING: This may make your authentication ticket more vulnerable to stealing, if someone can successfully carry out a cookie-stealing XSS attack.

1) Place this code in global.asax in the application root:

<script runat="server" language="c#">

void Application_PreSendRequestHeaders(Object source, EventArgs e)

{

      HttpApplication app = (HttpApplication)source;

     

      HttpCookieCollection cookies = app.Context.Response.Cookies;

      if (cookies != null)

      {

        foreach(string name in cookies)

        {

          HttpCookie cookie = cookies[name];

            if (cookie.Name.Equals(FormsAuthentication.FormsCookieName, StringComparison.OrdinalIgnoreCase))

            {

                  cookie.HttpOnly = false;

                  break;

            }

        }

      }

}

</script>

2) Make sure to set <modules runAllManagedModulesForAllRequests="true" /> in the application web.config to allow this code to run for media content.

Other alternatives:

1)      Make your media content publically available

2)      Use cookie-less Forms Authentication in the application, and use relative media urls with the media player or insert the cookieless ticket in the embedded media player urls.

Using cookie-less forms authentication is also not a great option, as it may make the entire application more vulnerable to the url-based ticket threats.  For more, see “Client Ticket Security” in http://msdn.microsoft.com/en-us/magazine/cc163702.aspx.

Hopefully this helps demystify this issue. Happy (media) serving!

 

Mike