-1

I'm trying to restrict anonymous users from browsing directly to a particular filename (image file) in a folder on my website. But when I turn on the "IIS Authentication" feature on the folder, both anonymous users and the website application can't access the image file.

How can I deny access to the file for anonymous users (for example, if the user were to type in the absolute url), but allow access to the website application? (I thought that maybe the "IP Address and Domain Restrictions" feature could be used, as well, but couldn't get it to work)

I could move the image file to a folder outside of the website, but then not sure how to use it in the .ImageUrl property.

...bump

EDIT - Solution (put following in a .aspx page and set the ImageUrl property to this page, with any needed querystring parameters):

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

If (Request.QueryString("FileType") IsNot Nothing) And (Request.QueryString("FileName") IsNot Nothing) Then

Try
' Read the file and convert it to Byte Array
Dim filePath As String = UrlXlat(Request.QueryString("FileType") & "\")
Dim fileName As String = Request.QueryString("FileName")
Dim contentType As String = "image/" & Path.GetExtension(fileName).Replace(".", "")

Dim fs As FileStream = New FileStream(filePath & fileName, FileMode.Open, FileAccess.Read)      
Dim br As BinaryReader = New BinaryReader(fs)
Dim bytes As Byte() = br.ReadBytes(Convert.ToInt32(fs.Length))
br.Close()
fs.Close()

'Write the file to Reponse
Response.Buffer = True
Response.Charset = ""
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = contentType
Response.AddHeader("content-disposition", "attachment;filename=" & fileName)
Response.BinaryWrite(bytes)
Response.Flush()
Response.End()

Catch ex As Exception
response.write(ex):response.end
End Try

End If

End Sub
swabygw
  • 813
  • 1
  • 10
  • 22

1 Answers1

0

You can move the file either to a folder outside of the root of the site or to the App_Data folder (which is protected form direct browsing by the ASP.NET framework) and then set your ImageUrl to point to a generic handler (.ashx file) which will be responsible for delivering the file to the browser. You perform your authentication checks in the handler.

I've written an article that provides implementation details: http://www.mikesdotnetting.com/article/122/simple-file-download-protection-with-asp-net

Mike Brind
  • 28,238
  • 6
  • 56
  • 88
  • Thanks, Mike. I did something along the same lines. I set the ImageUrl property equal to a .aspx page with the code added in above edit. – swabygw Feb 12 '15 at 07:29
  • Actually, I just discovered a hole in this - the user on the internet can simply browse to the .aspx page, use the parameters from the page source, and...voila...they can download the file. It gets served to them just like it was served to the web application. Thoughts? – swabygw Feb 12 '15 at 16:09
  • They won't be able to do that if you use a handler as suggested and check to see if the user is authenticated before transmitting the file. – Mike Brind Feb 12 '15 at 16:42
  • That would work, but then how would the website use the resource? Example, let's say it's a .jpeg file at, say, c:\dir\site\image.jpeg. Using the HttpHandler authentication method would certainly prevent random users from getting at the .jpeg file. But, the website has to show this image, too. So, what would be put in the .ImageUrl property of the image control? Whatever can be entered for that property, could be simulated by a user, no? The user can always simulate the site by typing in http://sitename/HandlingFile.aspx?parameters. The HandlingFile doesn't know the difference. – swabygw Feb 12 '15 at 17:36
  • The App_Data folder is good example of the problem. If I put the image file in there, nobody can browse it - great. But, the website can't display it, either. I could put an "allow" rule in for the website URL (say, "www.site.com") to let the website show the image, but then anyone could type in the same thing and get to the file, too. Any "file-streaming", handling file could also be browsed by a user and streamed directly to them by the same method. – swabygw Feb 12 '15 at 17:44
  • You set the ImageUrl to the url of the handler. The handler checks to see if the current user is authenticated. If they are, it transmits the image file. If not, get it to transmit another file. You put the logic to check if the request is authenticated in the ProcessRequest method of the handler. It's all in my article. – Mike Brind Feb 13 '15 at 09:57
  • Thanks, I can set the URL to the handler file. But the image is a public image (it's the logo for my website). So, it has to be available to the UN-authenticated user...but not steal-able (downloadable). If the unauthenticated were to the view the source and see the handler file, they could just put that URL into the browser and download the file. The image has to be available for viewing (by the unauthenticated), but not downloading. – swabygw Feb 14 '15 at 20:25
  • If a user can see an image on your site, it has already been downloaded to their computer. If you do not want people to "steal" your images, do not make them available on your site at all. – Mike Brind Feb 14 '15 at 21:56
  • That's what I was afraid of. I know there is a way to prevent "hot-linking", but I didn't see how to prevent downloading. I see the handler file as just a good way to provide content via authorization or from a non-public location on the server, but not to prevent downloading. But, thanks for your article - it was an excellent tutorial on programming a handler (I'm still going to use a handler - though it doesn't provide full protection, it does provide another step a hacker would have to take to steal the image). – swabygw Feb 14 '15 at 23:25