Craig
Craig

Reputation: 18724

Disable direct access to images

I am making a little family photo album, with the intention to maybe open it to other people to store images later.

I upload the images to ~\images\, then resize them 3 times (Normal view ... thumbnail and a tiny version) and move them to ~\images\thumbs, ~\images\normal, ~\images\tiny and then move the original to ~\images\original.

If a user knows a file name, they can just goto http://mysite.com/images/normal/filename.jpg for direct access.

I'd prefer that not to be available to them.

So, is there a way to change the ImageUrl of the asp:Image control, to rather read from a non-accessable folder? And would this be a performance hit? I'm thinking something like (Not sure if it's possible) reading the image into s Steam, and somehow setting the ImageUrl or what ever, to read from the stream?

Hope you can assist.

Upvotes: 10

Views: 10772

Answers (2)

ToddBFisher
ToddBFisher

Reputation: 11610

Might I suggest considering something like:

  1. Save images to a folder like "siteroot/images/userid/".
  2. Upon successful log in set a session variable so that other pages will know that the current user is logged in. Session["user"] = youruser; Whatever object you store in your session variable include a valid youruser.userID that is pulled from a database.
  3. In your Global.asax file on your site's root add something like:

(untested code)

void Begin_Request(object sender, EventArgs e)
{
    //Protect /images/ folder for all requests
    if (Request.FilePath.Contains("images"))
    {
        YourUser user = Session["user"];

        if(user == null) {
            Server.Transfer("404.aspx"); //Folder not public
        }

        if (!Request.FilePath.Contains("images/" + user.userID.toString())){
            Server.Transfer("404.aspx"); //This is not current user's image folder
        }

    }
}

this should effectively deny access to everyone but the correct user of their respective "images" folder, even if they figure out the direct path of the image files.

If anyone has any ways to improve this method feel free to comment as I will soon be implementing this idea in a site and second opinions are always welcome.

Upvotes: 0

competent_tech
competent_tech

Reputation: 44941

The answer is yes. You can use a special format of img src which will embed the image directly in the page.

Instead of the URL, you would use the following format:

<img src="data:image/png;base64,..." />

where data specifies the mime type of your image and the ... after base64, is the base64 encoded contents of the image.

This behavior is defined by this RFC.

Here is an example:

In the HTML:

<img id="MyPicture" runat="server" border="0" />

In the code-behind:

    protected void Page_Load(object sender, EventArgs e)
    {
        MyPicture.Src = @"data:image/gif;base64," + EncodeFile(Server.MapPath(@"/images/test.gif"));
    }

    private string EncodeFile(string fileName)
    {
        return Convert.ToBase64String(File.ReadAllBytes(fileName));
    }

Upvotes: 13

Related Questions