Media content in Sitefinity can be permissioned, which is great.  However in an unauthenticated state if the user clicks a link to the file from either an email link, or on the site somewhere they get a 401 response, not a link to your login page with a passthrough to the file.

Here's how you can get around that...

Step 1: Detect the error

Basically all we're doing here is capturing any error message related to documents so we can manually send them to the login page.

gistfile1.csView on GitHub
protected void Application_Error()
{
    //Sitefinity Logger should send to raygun now
    var exception = Server.GetLastError();

//Send document requests over to login
if(exception.Message.Contains("You are not authorized to 'View document'") || exception.Message.Contains("You are not authorized to 'View image'")){
    if (!ClaimsManager.GetCurrentIdentity().IsAuthenticated)
    {
        //If user is anonymous, send them to the login
        var defaultUrl = Config.Get<ProjectConfig>().DefaultSite.FrontEndLoginPageUrl;
        
        //Clear errors
        HttpContext.Current.ClearError();
        
        //Send the user to your loginpage
        Response.Redirect("{0}?ReturnUrl=/Download.aspx%3ffile={1}".Arrange(defaultUrl, HttpContext.Current.Request.Url.AbsoluteUri.Replace("?", "%3f")));
    }
}

//Other error processing like Raygun.io or whatever...

}

Step 2: Create the page\\widget to serve the file

So this could be an aspx page, ascx control, mvc control, simpleview widget...doesn't matter.  You just need something to serve them up the file.  I mean it's probably a better idea for this to be a sitefinity page that can be permissioned with a widget on it.  This code is just something we did a long time ago...

Download.aspxView on GitHub
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Download.aspx.cs" Inherits="SitefinityWebApp.Download" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script type="text/javascript"> var max_time = 5; var cinterval;

    function countdown_timer() {
        // decrease timer
        max_time--;
        document.getElementById('countdown').innerHTML = max_time;

        if (max_time == 0) {
            clearInterval(cinterval);

            window.location.replace(document.getElementById('downloadNow').getAttribute("href"));
        }
    }
    // 1,000 means 1 second.
    cinterval = setInterval('countdown_timer()', 1000);
&lt;/script&gt;

</head> <body> <form id="form1" runat="server"> <div> <p>Your download will start in <span id="countdown">5</span> seconds, <asp:HyperLink ID="downloadNow" runat="server" Text="Download Now" ClientIDMode="Static" /></p>

        Click &lt;a href="/"&gt;here&lt;/a&gt; to return to the dashboard
    &lt;/div&gt;
&lt;/form&gt;

</body> </html>

That's it!...next step is for telerik to get to making the functionality native without modification...or at least the ability to enable it.