Restrict access to PDF files on a password secured website

Posted on 2006-05-25
Last Modified: 2012-08-14
IIS sub directory - how to allow autorized users access only for users users that have logged on to a website

Restricting access of a .pdf document (e.g. 'Reader.pdf') to internal caller only.
Website IP address is The test directory to use is '/p1search'.

In IIS, under "Security" Tab  of "Property" of a particular directory (e.g. '/p1search'), the top part of the dialog box is "Enable anonymous access" - If checked, one specifies an account, whose default is 'ISER_WINDOWS2003' (Internal Guest Account). The others are 'IWAM_WINDOWS2003' (Launch IIS Process Account), 'Administrators', 'ASP NET', 'VUSER_WINDOWS2003' (?), etc. If not check, it doesn't ask for an accout.
The bootom part of this dialog box are four checkboxes: 'Integrated Window authentication','Digest authentication for Windows domain servers','Basic authentication (password is sent in clear text)', and '.NET Password authentication'.

The objective is to configure, using this security dialog box, is to restrict the access to a particular directory ('/p1search') from any callers that originates from within the same website (e.g. alone, i.e. any URL of the form "<directory><filename>" is accessable; whereas, any URL of the form "http://<website><directory><filename>" (e.g. '') has access to be denied. When I set anonymus account to be 'ON' using IUSR_WINDOWS2003, the this particular directory is accessable, including going through URL of the form "http://<website><directory><filename>" (this URL is entered at Address text box of an Internet Explorer (or of FireFox's one); evenmore, Google crawler can access this directory. But I desired to disable such access. Only place to access this directory ('/p1search') is to be called from .asp program's <a href="<directory><filename>" (e.g. '../p1search/Reader.pdf'), where this caller asp program resides at same server as this particular directory ('/p1search'), and at same website address ('').

If it is not with 'Security' dialog box, Right-clicking on a particular directory (e.g. '/p1search'), then submenu item 'Permission' may be so. In there, there are various system accounts (IUSR_WINDOWS, IWAM_WINDOWS, Administrators, ASP Net, etc..), having capable of setting permission parameters. The problem is WHICH account is Set to be 'enabled'; whereas, which one should set to be 'denied'.
Question by:GeorgeJacobson
    LVL 7

    Expert Comment

    OK I am trying to follow what you are asking so I'll try to break it out one at a time.

    If you want remove anonymous access just uncheck "allow anonymous access" and also using windows explorer go to that directory, right click, choose properties security and remove the "iusr_..." account.

    Now for only allowing access from the same web site I think what you are looking for is referrer.  The location of the client is always the IP address of their computer.

    you can use the servervariables collection to access where the client is being refered from.

    So for example:

    if instr(Request.ServerVariables("HTTP_REFERER"),"")  then
      'allow them access
      'access denied redirect them somewhere else.
    end if

    If you want to allow Google in, I know you said you didn't, but if you did you could do something like:

    if instr(Request.ServerVariables("HTTP_REFERER"),"")  OR instr(Request.ServerVariables("HTTP_USER_AGENT"),"googlebot") then

    So,  if your goal "is to restrict the access to a particular directory ('/p1search') from any callers that originates from within the same website"   You can simply use the referrer check and ignore the other security settings.

    Just be aware that while this will keep out 99% of the people a motivated and knowledgeable person could spoof the referrer.  So don't use this method to secure things like customer credit cards :)


    Author Comment

    Thx (sorry for the confusing question layout),

    Basically I am trying to restrict access to PDF files on a password secured website  ( I can provide you a test ID/PW for if this helps)
    Currently the p1search directly is checked on for "allow annonymous access", so anyone can access the pdf file.  I wish to restrict it only to authorized web-site users ie those that have logged on to the site  
    Given that it is a pdf file, I don't know how I can embed the referrer check.  I did find a PHP solution but do not know how to implent this in ASP or HTML.

    More often, The referrer to .pdf file is accessed by executing <a href="/p1search/Reader.pdf"> HTML tag. This <a href - - - > tag can be found in pure HTML source code (a client-side code). What I would want to do is that: if source HTML code resides in same web site address (e.g., document 'Reader.pdf' is accessable; hoverver, if one access from outside (including typing http;// URL address in Internet Explorer or Firefox (or even by Google crawler), access to 'Reader.pdf' and content of entire directory '/p1search' should be denied.

    Using if-then-endif construct in ASP code would not work because it is server-side processing. This ASP contruct uses '' if instr(Request.ServerVariables("HTTP_REFERER"),"") then  'allow access  ''. Use of embedding .pdf file in ASP code also would not work because one can by-pass that ASP code: instead, one can access to this .pdf directly.

    As for Google, I am ok with the Google crawler indexing the pdf file, as long as no-one can access it.

    THX alot!
    LVL 7

    Expert Comment

    One way to do it would be to use SERVERXMLHTTP object with authentication. Its a bit convoluted so let me just outline the solution.  

    1) create a secure directory for your PDF and a special account to acces it lets call it  'pdfaccount'

    2) Create an ASP page that does the referer check. If they are accessing from your website then
        Use SERVERXMLHTTP object with authentication to fetch the PDF from the secure directory and then stream it out to the client.

    This way the only way to access the PDF is via your script that passes the 'pdfaccount' credentials, direct access would fail.

    Here is an example of passing login information from SERVERXMLHTTP (the example is in jscript but you can convert to vbscript easily enough.

       var objSrvHTTP;
       objSrvHTTP = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0"); ("GET","http://someotherserver/secure.asp",false, _
                           "testuser", "testpassword";
       objSrvHTTP.send ();
       Response.ContentType = "text/xml";
       Response.Write (objSrvHTTP.responseXML.xml);

    Also, this example looks incomplete to me, I remember having to do two requests, but maybe that was accessing HTTPS...


    Author Comment

    Regarding step #1, how do I create a special account to be called 'pdfaccount ? I cannot simply enter any arbitrary name by clicking on 'Add' button of 'Security' tab of a directory's property. When I do, I get error message: "Cannot find 'pdfaccount'" because 'pdfaccount is not on the list. Exactly what do I mean by special account 'pdfaccount', and how Do I establish such account ?

    Thank-you very much.
    LVL 7

    Expert Comment

    What I mean is a windows user account. IUSR_ is just a special windows account used for anonymous access. What you want is a directory that IUSR_ does not have access to. So go to computer management create a windows account, name it whatever you want.

    Then create a directory and assign this account read permissions and make sure IUSR does NOT have read permissions.

    OK, so now on your website create a script that checks that they are being refered by your site and if they are you can use the SERVERXMLHTTP obejct to select the PDF from teh secured directory. Since that directory does not allow access by IUSR_ you will add the username you created to the SERVERXMLHTTP obejct to make an authenticated request.

    The overall point of this method is that ISUR_ is running a script that will use a different account to access the PDF via the SERVERXMLHTTP object.  So only the script has access to the file and the user can not deep link to it.  

    This is kinda an advanced technique as you will probably run into problems figureing out how to use SERVERXMLHTTP to fetch and restream the binary out to the client.

    You'll have to decide how important it is and if it is worth the effort. I don't know of any easier method.

    Author Comment

    Sorry, have been away.
    I have set up the Windows user account and will try your recommendation later today and will let you know.

    Author Comment

    In IIs, I unchecked "Anonymous Access" for directory '/p1search' in its Security settings.
    In Windows Explorer, I right-click on directory '/p1search', choose Properites, then Security tab,
    and removed 'IUSR_' account so that there is no anonymous access.

    In ASP code, I have added object "Msxml2.ServerXMLHTTP.6.0".
    To use this object, I have downloaded "msxml6" (MSXML Parser 6.0) from
    The ASP vbscript is as follows:

        Dim objSrvHTTP
        Set objSrvHTTP = Server.CreateObject("Msxml2.ServerXMLHTTP.6.0") "GET", "", False, "<account>", "<password>"
        Response.Write objSrvHTTP.responseXML.xml

    Followed by, in HTML, statment

        <a href="p1search/Reader.pdf"><u>Test PDF forms</u></a>

    I notice that, in statement " "GET", ...", URL must contain web-side address; otherwise I get an error.
    I have tested on my localhost. There, this statement will then be read:      "GET", "http://localhost/p1search/Reader.pdf", False, "<my localhost account>", "<its password>"

    But I still dont get my results !!

    Instead, the screen ouput is produced as the folowing:

    - <html>
      - <head>
          <title>Test PDF</title>
      - <body leftmargin="0" rightmargin="0" topmargin="0" bottommargin="0">
        - <a href="p1search/Reader.pdf">
            <u>Test PDF forms</u>

    Even if when its corresponding source code generated is as follows:

    <title>Test PDF</title>
    <body leftmargin="0" rightmargin="0" topmargin="0" bottommargin="0">
          <a href="p1search/Reader.pdf"><u>Test PDF forms</u></a>

    It is like an expanding XML tree structure. I clicked on <a href  > statement, nothing happens!  No pdf viewing.

    However, If I removed last two statements "Response.ContentType="text/xml" and Response.Write objSrvHTTP.responseXML.xm",
    Then It goes ordinarily to next HTML page, containing a hyperlink to "Reader.pdf" document file.
    Unfortunately, whether it can be access or not is still not working: when I have denied IUSR_ account but grant only
    to specific account "<my localhost account>" and "<its password>", I get "Enter network password" dialog box; if "cancel",
    I get "You are not authorised to view this page" message. (If I entered with an authorized account, e.g. Administrator,
    I have accessed "Reader.pdf"; but this method of entering authorized Username/Password becomes too cumbersome
    for most ordinary member users; and therefore, there must be a way to automatically process with such authorized Username/Password.)

    On the other hand, If I grant an anonymous access in Security, I am able to access "Reader.pdf" BUT unfortunately,
    at the cost that "Reader.pdf" can be accessed directly by anyone!

    I beleave that I don't know how to use XML coding becuase I treat them like an HTML code.
    I would like to know how to program in ASP that contains a reference (via '<a href   >')
    to 'Reader.pdf' in ASP page, apart from using ServerXMLHTTP object.
    LVL 7

    Expert Comment

    There should be no other HTML nor anything else written out to the clients browser.

    Your page should look sort of like this:
    'if locally referered then "GET", "", False, "<account>",  "<password>"
       Response.ContentType= "whatever the mime type for PDF is"
      Response.BinaryWrite objSrvHTTP.responseBody
    'end if

    Tell you what I have read a few questions like this so I'll write up an article for one of my sites with a tutorial and then come back and post the link. Hoipefully today :)

    LVL 7

    Accepted Solution

    OK So I created a directory under one of my sites called securePDF and set IUSR_ to denied.

    If you try accessing this pdf file directly you should be prompted to login.

    To make sure that people can access this file without having to login, BUT only under circumstances that I can control in script I created the following page.  When you follow this link it should load the PDF for you.

    The code on this page is:
    Set objSrvHTTP = Server.CreateObject("Msxml2.ServerXMLHTTP.4.0")
    with objSrvHTTP
          .open "GET", "", False, "[username]",  "[password]"
          Response.ContentType= "application/pdf"
          Response.BinaryWrite .responseBody
    end with

    And nothing else.

    The script on getSecurePDF.asp is a proxy which makes an authenticated connection to the secure directory, fetches the document, and then streams it back out to the client.

    No, I just need to find those other people who were asking this question :)

    btw: I used Msxml2.ServerXMLHTTP.4.0 instead of Msxml2.ServerXMLHTTP.6.0  because I didn't want to take the time to upgrade.  It *should* work in 6 but if not just change it to 4 and that version might still be on your server.

    Author Comment

    Thank you very much.  We have implemnted & tested your solution successfully!

    We installed msxml6.msi, in the IIS Directory security, Authenitiacation method, set no Annoynmous access, checked Integrated Windows Authentication. In Windows Explorer for the sub-directory security tab: Deny permission to Every_Body and ISR, then we created an account.  

    As you pointed out, once the user has accessed the pdf file, via the ASP page (ie logged in to the web-site), then the account User Name/Password seems to be kept in the cache and can be acccessed directortly from the file path with the pdf extension (but must have already accessed once via a log-in).

    THX again:-)
    LVL 7

    Expert Comment

    >User Name/Password seems to be kept in the cache and can be acccessed

    I don't think its a cache I think its for the session only. But, I havn't tested that.

    Author Comment

    Yes - I believe you are correct, upon further testing, we agree - it is the session .  Close down the browser and the file path can not be reached.

    Again, THX ALOT for your help (and perseverence), you were absolutley amazing in your help!  Kudoos to you - you really helped us out of a "jam"! :-)


    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Better Security Awareness With Threat Intelligence

    See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

    I was asked about the differences between classic ASP and ASP.NET, so let me put them down here, for reference: Let's make the introductions... Classic ASP was launched by Microsoft in 1998 and dynamically generate web pages upon user interact…
    This demonstration started out as a follow up to some recently posted questions on the subject of logging in: and…
    Internet Business Fax to Email Made Easy - With eFax Corporate (, you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
    Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

    759 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    8 Experts available now in Live!

    Get 1:1 Help Now