5

I have the following case , and i wanna to ask what's the best solution ?

I have a specific file i wanna specific users(according to some permissions) to download this file .

so i show this file only for the authorized users, but what if someone(not authorized) recognize the file link(knows the link url) and download it !!

How to allow this file to be downloaded only by the authorized users .

Shai
  • 25,159
  • 9
  • 44
  • 67
Anyname Donotcare
  • 11,113
  • 66
  • 219
  • 392

4 Answers4

4

Put the file into a directory which is not served by the web server and implement a handler for the "virtual url" which in turn checks for permissions etc. - a possible way would be an ASHX handler (see here for sample code and here for MSDN reference).

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • Could u explain more what do u meant by `Put the file into a directory which is not served by the web server` please ? – Anyname Donotcare Apr 02 '12 at 09:01
  • 1
    @just_name I mean put the file(s) into a place which IIS does not know about so that anyone "guessing" links can't get to the file because IIS does not know about it. Your handler then serves the file by accessing that place after checking permissions etc. – Yahia Apr 02 '12 at 09:04
  • is it possible for the `generic handler` to access file which is out of the iis – Anyname Donotcare Apr 02 '12 at 09:08
  • One more question please . is `app_data` folder is secure and can't be accessed through web ? because i do the following :`context.Server.MapPath("~/App_Data/") + "myfile.xlsx";` is this secure? – Anyname Donotcare Apr 02 '12 at 11:48
  • 1
    @just_name AFAIK by default access from the web to App_Data will be denied by a special ASP.NET-HTTPHandler - as long as you are using the default settings this should be secure... – Yahia Apr 02 '12 at 12:01
4

My answer would be: Dont use direct links!

Create a Download.aspx and have the links for downloads post to Download.aspx?params

The params should be encrypted/hashed containing the filepath+name to download and session_id.

On Download.aspx validate that the session_id is valid and active on the browser.

This should allow you to allow downloads to the correct folks only:

If you add to the params also the user_id or the user_type you can deny/permit download on the onLoad of Download.aspx

Pedro Ferreira
  • 629
  • 3
  • 8
1

The best way would be to add httphandlers and check whether the requested file have special permissions or not, an example for what I said would be:

        using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;

public class MyHTTPHandler : IHttpHandler, IRequiresSessionState
{

string myFile;
public bool IsReusable {
    get { return true; }
}

public void ProcessRequest(System.Web.HttpContext context)
{
    myFile = context.Request.Path;
    if (myFile.ToLower().Contains("members private files") || myFile.ToLower().Contains("members%20private%20files")) {
        if (System.Web.HttpContext.Current.Session["Login"] == null) {
            context.Response.Redirect("~/NotAuthorized.aspx");
        } else {
            if (myFile.ToLower().Contains("privatefiles")) {
                StartDownload(context, myFile);
            } else {
                if (IsMemberAuthoraizedToDownloadFile(context)) {
                    StartDownload(context, myFile);
                } else {
                    context.Response.Redirect("~/NotAuthorized.aspx");
                }
            }
        }
    } else {
        StartDownload(context, myFile);
    }
}

private void StartDownload(HttpContext context, string downloadFile)
{
    context.Response.Buffer = true;
    context.Response.Clear();
    context.Response.AddHeader("content-disposition", "attachment; filename=" + downloadFile);
    context.Response.ContentType = "application/pdf";
    context.Response.WriteFile(downloadFile);
}

// just my own function to check if user is valid

private bool IsMemberAuthoraizedToDownloadFile(HttpContext context)
{
    GroupMembersControl MyGroupMemberc = new GroupMembersControl();
    System.Collections.Generic.List<GroupMembers> MemberGroupsL = MyGroupMemberc.GetMemberGroups(System.Web.HttpContext.Current.Session["Login"]);
    MemberGroupControl MyGroupC = new MemberGroupControl();
    MemberGroup MyGroup = default(MemberGroup);
    foreach (GroupMembers groupmember in MemberGroupsL) {
        MyGroup = MyGroupC.GetMemberGroup(groupmember.GroupID);
        if (myFile.ToLower().Contains(MyGroup.Name.ToLower)) {
            return true;
        }
    }
    return false;
}
    }
Alex
  • 5,971
  • 11
  • 42
  • 80
1

The following link provides details on Authorization Rules in iis and asp.net, it seems pertinent to your question.

Firstly you want to ensure ASP.NET handles request for your specified file type. You can configure this in IIS (see link below).

Secondly, you will then need to update your web.config to deny anonymous users from reaching your url, providing that you are using rolemanager :

 <roleManager defaultProvider="SqlProvider" enabled="true" cacheRolesInCookie="false"     
   cookieName=".ASPROLES" cookieTimeout="30" cookiePath="/" cookieRequireSSL="false"  
   cookieSlidingExpiration="true" cookieProtection="All">
  <providers>
    <add name="SqlProvider" type="System.Web.Security.SqlRoleProvider" 
        connectionStringName="membership" applicationName="yourApplication"/>
  </providers>
</roleManager>



<location path="path/file.extension">
      <system.web>
      <authorization>
         <deny users="?"/>
       </authorization>
     </system.web>
   </location>

IIS 6 ignores Web.config authorization settings

Community
  • 1
  • 1
Shay
  • 353
  • 1
  • 11