How to retrieve asp.net media / resources based on logged in user?

232 Views Asked by At

I have an asp.net web api project using token based authentication. my app uploaded and retrieve images and I keep file path in table_myfiles along with the uploaded user ID.

I would like the user to access only the files he have uploaded, which I can identify from the table.

How to protect my resources to restrict access to only to the user based on table_myfile ? And not to anyone without logging in or direct link / path ?

I have been searching for any possible solution for a week now , I think I should implement a middleware to manage access. But I couldn’t find any resources on how to implement the same.

Currently my api shows all resources just by directly accessing the file path/link.

1

There are 1 best solutions below

14
On BEST ANSWER

The simple apporach is to remove the vitural folder, or that folders from the web site folders. That way, no simple URL exists for any of the files.

So, for a user to get/see/use/download a file? You present say a listview or some kind of grid (or repeater) that displays and lists out the files.

Then, when they want to download or view a file?

You use response.write and stream the file down to the client side.

Remember, on the server, code behind uses 100% clean and correct windows file paths. For any web based URL, then that folder must be in a valid path of the web site. When they type in a valid URL, it eventually gets translated to that given folder in the site (or a external folder provided when you create a mapped "virtual" folder in IIS. However, if you don't provide that virtual folder, or the folder is NOT in the web site file/folder sets, then no valid URL's exist. However, that folder can be directly used and hit with code behind - any valid server path/folder name is allowed in code behind.

Because when streaming the file, you need path name, file name, AND ALSO the "mine" type. Thankfully, .net 4.5 or later has this ability.

so, from a database (table) I display the file names like this:

enter image description here

But, if you click on the preview image, that is a image button.

The code behind simply gets/grabs the file name from the database.

I then download (stream) the file to the browser side like this:

if (File.Exists(strInternalFullPath))
{
    string strConType = MimeMapping.GetMimeMapping(strInternalFullPath);

    binFile = File.ReadAllBytes(strInternalFullPath);
    Response.ContentType = strConType;
    Response.AppendHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(strWebUrl));
    Response.BinaryWrite(binFile);
    Response.End();
}
else
    MyToast2(this, btnLink.ClientID.ToString, "File Not found", "We no longer have this file avaiable.");

so, this buttion behaves 100% like a link, but there are no existing URL's or path name that points to the files folder from a web based URL.

Remember:

Web based URLs - they auto map from the web site URL to a existing folder.

You can use server.MapPath("some url to file") to "translate" this to a internal file name.

Code based files:

In your .net code (code behind) ANY file name is a standard plane, jane file name that points to a file on the server.

so, once we have that file name from the database, you can steam the file as if the user clicked on a link. But you never have to expose the actual file name, or file path. And no such valid URL's exist on the web site, since you do NOT have that files folder in the web site folder hierarchy - but placed that folder outside of the web site.

As long as that folder is outside of the web folders, and as long as you don't setup a virtual folder that points to that folder outside the web folders?

Then code behind can STILL get/grab/see/use any file on the server. that code uses a full valid windows file name, - but the web site will have no mapping to such a folder - hence no valid URL's will exist or can be typed in.