IIS Authorization and Restrictions - asp.net

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

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

Related

Serve Local Files in ASP.NET in Chrome

Chrome has a setting that blocks the opening of local files. The specific error you get is Not allowed to load local resource: file:///<file name>. I'm trying to develop an internal site for us to access these files but as many users are using Chrome, I need a workaround to serve these files.
Currently, to get my files and display them, I have this logic:
For Each file As String In Directory.GetFiles("<file path>")
fileInfo = New FileInfo(file)
fileList.Add(fileInfo)
Next
fileList.Sort(Function(x, y) x.Name.CompareTo(y.Name))
For i As Integer = 0 To fileList.Count - 1
pnlLinks.Controls.Add(New LiteralControl("<br />"))
pnlLinks.Controls.Add(New LiteralControl("" & fileList(i).Name & ""))
pnlLinks.Controls.Add(New LiteralControl("&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp"))
pnlLinks.Controls.Add(New LiteralControl("<span>" & GetByteSize(fileList(i).Length.ToString) & " </span>"))
pnlLinks.Controls.Add(New LiteralControl("<br />"))
Next
The a href is a little funky because I've been experimenting with different folder structures to get this working, but it should not be relevant.
I had the idea of implementing a function that could send this to a byte stream but I'm not experienced in that area and wouldn't be sure how to implement it.
I was able to resolve this with a FileStream and launching to a new page that handles it on Page_Load
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim pdfFileStream As FileStream = Nothing
Dim pdfFileSize As Long = 0
Dim pdfPath As String = "<file path>"
pdfFileStream = New FileStream(pdfPath, FileMode.Open)
pdfFileSize = pdfFileStream.Length
Dim Buffer(CInt(pdfFileSize)) As Byte
pdfFileStream.Read(Buffer, 0, CInt(pdfFileSize))
pdfFileStream.Close()
Response.ContentType = "application/pdf"
Response.OutputStream.Write(Buffer, 0, pdfFileSize)
Response.Flush()
Response.Close()
End Sub

The request is not supported. Encrypting an Image in ASP.net

I am trying to create a simple encryption program with visual basic on visual studio. My program is to encrypt an image then decrypt it. The system is saying that the request is not supported. As a note I am just learning about encrypting and not sure if I am even doing this correctly. Any comments or help would be much appreciated.
Error is from this: File.Encrypt(FileName)
if my encrypt is creating an error then my decrypt will most likely as well
Imports System
Imports System.IO
Imports System.Security.Cryptography
Partial Class _Default
Inherits System.Web.UI.Page
'My Encrypt button that takes the file from my FileUpload tool and Encrypts it, then outputs on my label
'that the file was successfully encrypted
Protected Sub EncryptButton_Click(sender As Object, e As EventArgs) Handles EncryptButton.Click
Dim FileName As String = FileUpload1.FileName
File.Encrypt(FileName)
Label1.Text = "Encrypt" + FileName
End Sub
'My Decrypt button that takes the file from my FileUpload tool and Encrypts it, then outputs on my label
'that the file was successfully encrypted
Protected Sub DecryptButton_Click(sender As Object, e As EventArgs) Handles DecryptButton.Click
Dim FileName As String = FileUpload1.FileName
File.Decrypt(FileName)
Label1.Text = "Decrypt" + FileName
End Sub
'Load page that will display a success output on the label if the upload is completed
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If FileUpload1.HasFile = True Then
Label1.Text = "Success"
Else
Label1.Text = "Failed"
End If
End Sub
Protected Sub CustomValidator1_ServerValidate(source As Object, args As ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
'Verify the control has a file
If Not FileUpload1.HasFile Then
CustomValidator1.ErrorMessage = "A file is required in order to proceed"
args.IsValid = False
Else
'next 2 lines are all one line
Dim ext As String =
System.Web.VirtualPathUtility.GetExtension(FileUpload1.FileName).ToUpper()
If Not ext = ".GIF" And Not ext = ".JPG" And Not ext = ".PNG" Then
'next 2 lines are all one line
CustomValidator1.ErrorMessage = String.Concat("Invalid file type '", ext, "' -must be .gif or .jpg or .png to continue")
args.IsValid = False
Else
args.IsValid = True
End If
End If
End Sub
End Class
I searched for "System.IO.IOException" and found Troubleshooting Exceptions: System.IO.IOException which states
Make sure the file and directory exist.
Then looking at the code:
Dim FileName As String = FileUpload1.FileName
I see that there is no directory specified for the file. So, you need to use Path.Combine so that you can give File.Encrypt the full filename including the path.
(There is no indiction in the posted code of which directory the uploaded file is in, so I can't help further with that. It could be that FileUpload1 has a property which gives that.)

Streaming PDF works on Localhost but not on published Website

I'm currently trying to open a PDF file on my website that is located on my company's network. I had this working previously, but now for some reason it isn't working. Here is what I have:
I am using impersonation to access the file. It has domain admin privileges. This is from my web.config file (username/password are altered):
<identity impersonate="true" password="pass" userName="domain\user" />
I use this code to open the PDF in a window:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Dim strPath As String = CStr(Session("DWGPath"))
strPath = "file://san01/prodeng/" + Mid(strPath, 4)
strPath = Replace(strPath, "\", "/")
Dim pdfPath As String = strPath
Dim client As WebClient = New WebClient()
Dim buffer As Byte() = client.DownloadData(pdfPath)
Response.ContentType = "application/pdf"
Response.AddHeader("content-length", buffer.Length.ToString())
Response.BinaryWrite(buffer)
Response.End()
Catch exa As WebException
Response.Redirect("DrawingError.aspx")
Catch ex As Exception
Throw ex
End Try
End Sub
This doesn't work. It redirects me to the "DrawingError.aspx" page. This link dispalys the "Session("DWGPath")" variable. I can take this variable and paste it in to my browser and the PDF opens without problem.
However, if I alter my code to this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
Dim strPath As String = CStr(Session("DWGPath"))
Dim pdfPath As String = strPath
Dim client As WebClient = New WebClient()
Dim buffer As Byte() = client.DownloadData(pdfPath)
Response.ContentType = "application/pdf"
Response.AddHeader("content-length", buffer.Length.ToString())
Response.BinaryWrite(buffer)
Response.End()
Catch exa As WebException
Response.Redirect("DrawingError.aspx")
Catch ex As Exception
Throw ex
End Try
End Sub
It still doesn't work.
The account also has full control privileges to the folder that contains the PDFs.
Any help or insight would be appreciated. Thank you!
EDIT: IF I throw exa then I get this:
The account used is a computer account. Use your global user account or local user account to access this server.
I assume you're running IIS. Go to the application pool for this app and change the identity that it's running under to be the domain\user account. See if that fixes your problem.
You want to make sure that the password on this account doesn't change or else it will fail when the password expires.

asp.net can't continue after response.binarywrite

I have the following code which successfully writes a pdf to the client. The problem is that I can't get any code after this to execute. It's the last step of a wizard, and despite putting this in the ActiveStepChanged handler, it never makes it to the confirmation/final page.
Response.Clear()
Response.ContentType = Nothing
Response.AddHeader("content-disposition", "attachment; filename=" & FileName)
Response.BinaryWrite(data)
Response.Flush()
Basically, there's a checkbox that the user checks if they want to download the file when they hit the Finish button. I don't want to have a separate button to download the file because users have been known to get confused and think that by pressing the download button that they've completed the necessary steps and never complete their application (we're talking about non computer literate users here). So it all works, except it doesn't make it to the confirmation step when they select that option.
How can I ensure that processing continues after downloading the file?
The best way is to write this code in a HttpHandler and call Response.End after Response.Flush.
I figured this one out myself. Basically, I placed the response.binarywrite code (listed in op) in the code behind of its own empty webform. I then call then use the javascript openwindow function in ScriptManager.RegisterClientScriptBlock to open it.
Code in original page:
Me.Session("PrintApplication") = data
Me.Session("PrintApplicationFileName") = FileName
ScriptManager.RegisterClientScriptBlock(Me, Me.GetType, "PrintReport", "window.open('PrintApplication.aspx');", True)
Code in PrintApplication.aspx:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Me.Session("PrintApplicationFileName") <> Nothing Then
Dim data As Byte() = Me.Session("PrintApplication")
Dim FileName As String = Me.Session("PrintApplicationFileName")
Me.Session("PrintApplication") = Nothing
Me.Session("PrintApplicationFileName") = Nothing
Response.Clear()
Response.ContentType = Nothing
Response.AddHeader("content-disposition", "attachment; filename=" & FileName)
Response.BinaryWrite(data)
Response.Flush()
Response.End()
End If
End Sub
Works perfectly

download a ftp file

I am trying to download a ftp file from my online webserver. The file resides in ftp100-0 and is the only file in there. The error code states:
The requested URI is invalid for this FTP command.
Here is my code:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
' Get the object used to communicate with the server.
Dim request As FtpWebRequest = DirectCast(WebRequest.Create("ftp://www.mysite.com/"), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.DownloadFile
' This example assumes the FTP site uses anonymous logon.
request.Credentials = New NetworkCredential("ftp100-0", "password")
Dim response As FtpWebResponse = DirectCast(request.GetResponse(), FtpWebResponse)
Dim responseStream As Stream = response.GetResponseStream()
Dim reader As New StreamReader(responseStream)
Console.WriteLine(reader.ReadToEnd())
Console.WriteLine("Download Complete, status {0}", response.StatusDescription)
reader.Close()
response.Close()
End Sub
Try the URL you are providing from a web browser to ensure it is correct. The file name is missing from the URL.

Resources