|
 |
asp_web_howto thread: Securing Download Files
Message #1 by "Gisella" <peregrine@e...> on Tue, 24 Dec 2002 01:55:10
|
|
What's the best way to secure download files that I only want to make
available to people who have purchased them from my storefront?
I'm setting up a storefront. Once a customer purchases a software product
from my site, and his credit card transaction is processed and approved,
he is redirected to the file to download (response.redirect). The file
resides on a website with anonymous access. So anyone who knows the exact
URL to the download files can freely download them :( obviously not very
secure. Even if I kept the URL secret, download managers (e.g., DAP and
M0Zilla) will find the URL and store it in their database and published to
all their users.
I came across http://www.artisticcheese.com/tech/binary/, that describes
how to read the entire download file into memory and send it in chunks to
the client. Below is the basic code involved:
REsponse.ContentType = "application/x-msdownload"
REsponse.AddHeader "Content-Disposition", "attachment;filename=" + Request
("file_name")
Response.ContentType = "application/octet-stream"
Set objASPBinary = CreateObject("ASPDownload.ChunkBinaryFiles")
strFileName = Server.MapPath (Replace (strDOWNLOAD + Request
("file_name"), "/", "\"))
For Each chunk In objASPBinary.readFile(strFileName)
If Response.IsClientConnected THen Response.BinaryWrite chunk Else
Response.End
Next
Set objASPBinary=Nothing
This method has a serious drawback if we are talking about heavily used
sites: first, the ASP engine would have to read the whole file into memory
(which can eat significant amount of memory and time); and second, since
the file is dynamic, it would have to be processed by theASP engine and
one would have to go through limitation of dynamic content in terms of the
number of concurrent threads (which are limited to 25 per processor by
default for IIS5). By default, one would have a maximum of 25 users with
very heavy disk I/O and processor resources for that method.
Do you know of a better approach to this problem? One idea I have is to
put the download files in a folder that is protected by means of Basic
Authentication. I would then direct the customer to the files with the
username and password in the header, so they're not prompted for such. Is
this at all possible? If so, how do I do it? If not, what other approach
do you recommend?
Thanks,
Gisella
Message #2 by Jack_Speranza <jsperanza@g...> on Tue, 24 Dec 2002 10:07:36 -0500
|
|
On December 23, 2002 Gisella said:
> What's the best way to secure download files that I only want
> to make available to people who have purchased them from my
> storefront?
>
> ...
>
> This method has a serious drawback if we are talking about heavily
> used sites...
Hi Gisella --
What is your definition of "heavily used sites?" I have implemented
what is essentially this solution on a couple of different sites
that transfer some fairly large files under IIS 4.0. Granted, we're
using some fairly good horsepower machines in a two or three server
web farm, but it would take a great deal of activity to bring us
down (activity which we've never experienced).
On average, a 1 MB file will transfer in about 180 seconds over a 56K
modem conneciton vs. 6 seconds over a T1 type connection (cable modem,
some xDSL connections). Naturally, much depending on server load, network
traffic, and other external variables. Similarly, a 10MB file would take
about ten times as long (1800 seconds or 30 minutes on a 56K modem vs.
3 minutes on a T1 type conneciton). If the size of the files you are
downloading range between these amounts, and your typical user connection
varies from modem to cable modem, then the actual time you are tying up
your script engine with binary transfers lies anywhere between 6 seconds
to 30 minutes). Do you expect a lot of people clamoring to download files
at the same time, or do you expect the load will be pretty evenly spread
across the clock? What is the average amount of files per day (hour, or
whatever metric you wish to use) you expect to transfer? Hard to tell
whether you need to worry about server load without some numbers...
In the ASP implementations I've built, we work in a little bit of a
safeguard
against long server loads by setting the ASP script to timeout after 10
minutes (just in case we get a user on a 56K modem trying to download a
monster file -- for those people, we'll pay the expense of sending a CD via
mail ;-) A low tech solution that works just fine...
In any event, not sure if this helps or not, but thought I'd throw these
questions out just in case you're heading off to build something that you
don't necessarily need...
Happy New Year!
Jack
Message #3 by "Owen Mortensen" <ojm@a...> on Tue, 24 Dec 2002 08:53:43 -0700
|
|
You might also write a cookie with the username and password encrypted
(and time-sensitive so it only works for then next hour or so). Once
they get to the file, you retrieve the cookie and authenticate them to
the LDAP (this is SiteServer?) (See below). Once they are
authenticated, then they can download the file(s)...
(From the Wrox book, "Site Server 3.0 Personalization and Membership" by
Robert Howard)
Set x = Server.CreateObject("Membership.Verifusr.1")
strURL = Request.Form("URL")
strUsername = Request("Username")
strPassword = Request("Password")
Y = x.VerifyCredentials(strUsername, strPassword, strURL)
If y = "" then
response.write "Login failed"
response.end
Else
response.redirect y
End if
Note that you'll want to change the username and password so it comes
from the cookie instead of a form (keeps them hidden) and do some extra
checking to make sure they're not expired. Then you can redirect to the
file download that is protected by the basic authentication....
Hope this helps
Owen
-----Original Message-----
From: Gisella [mailto:peregrine@e...]
Sent: Tuesday, December 24, 2002 1:55 AM
To: ASP Web HowTo
Subject: [asp_web_howto] Securing Download Files
What's the best way to secure download files that I only want to make
available to people who have purchased them from my storefront?
I'm setting up a storefront. Once a customer purchases a software
product
from my site, and his credit card transaction is processed and approved,
he is redirected to the file to download (response.redirect). The file
resides on a website with anonymous access. So anyone who knows the
exact
URL to the download files can freely download them :( obviously not
very
secure. Even if I kept the URL secret, download managers (e.g., DAP and
M0Zilla) will find the URL and store it in their database and published
to
all their users.
I came across http://www.artisticcheese.com/tech/binary/, that describes
how to read the entire download file into memory and send it in chunks
to
the client. Below is the basic code involved:
REsponse.ContentType = "application/x-msdownload" REsponse.AddHeader
"Content-Disposition", "attachment;filename=" + Request
("file_name")
Response.ContentType = "application/octet-stream"
Set objASPBinary = CreateObject("ASPDownload.ChunkBinaryFiles")
strFileName = Server.MapPath (Replace (strDOWNLOAD + Request
("file_name"), "/", "\")) For Each chunk In
objASPBinary.readFile(strFileName)
If Response.IsClientConnected THen Response.BinaryWrite chunk Else
Response.End
Next
Set objASPBinary=Nothing
This method has a serious drawback if we are talking about heavily used
sites: first, the ASP engine would have to read the whole file into
memory
(which can eat significant amount of memory and time); and second, since
the file is dynamic, it would have to be processed by theASP engine and
one would have to go through limitation of dynamic content in terms of
the
number of concurrent threads (which are limited to 25 per processor by
default for IIS5). By default, one would have a maximum of 25 users with
very heavy disk I/O and processor resources for that method.
Do you know of a better approach to this problem? One idea I have is to
put the download files in a folder that is protected by means of Basic
Authentication. I would then direct the customer to the files with the
username and password in the header, so they're not prompted for such.
Is
this at all possible? If so, how do I do it? If not, what other
approach
do you recommend?
Thanks,
Gisella
Message #4 by "Gisella" <peregrine@e...> on Tue, 24 Dec 2002 18:38:03
|
|
Thanks !
I think I'll use this code instead, which I got from another board. In
that way, I don't have to use a compiled VB component.
Gisella
<%
file1 = "../../text1.txt"
file2 = "../../text2.txt"
file3 = "../../text3.txt"
df = Request.Querystring("df") 'download file
if(len(df)<>0) then
Dim Stream, Contents, nameoffile
nameoffile = df
Response.ContentType = "application/octet-stream"
Response.AddHeader "content-disposition", "attachment;
filename=filedownload.zip" 'name to appear to the usr
Set Stream = server.CreateObject("ADODB.Stream")
Stream.Open
Stream.LoadFromFile
Server.MapPath(nameoffile)
Contents = Stream.ReadText
Response.BinaryWrite Contents
Stream.Close
Set Stream = Nothing
End if
%>
|
|
 |