6

I am using ASP.Net MVC. I have restricted access to the web site using ASP Forms authentication. However, the web pages contain links to pdf files on the server which I also want protected.

For example, the user can browse to foo.com and foo.com/account/logon. Once they logon they can access foo.com/category/bar which presents the view in bar.aspx. On that view is a link to foo.com/files/theta.pdf which loads up in the browser just fine. However, I don’t want foo.com/files/theta.pdf accessible from the browser unless the user has authenticated.

How do I prevent a user from accessing foo.com/files/theta.pdf directly from their browser without first authenticating at foo.com/account/logon?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Jeff Rubingh
  • 183
  • 1
  • 10

4 Answers4

8

Pass the request through a controller, and return a FileResult. You can apply whatever security you want to the controller method, either by using the Authorize attribute, or by checking permissions inside the controller method.

There is an example of such code at this question, which illustrates how to return an image file. Just return your pdf instead of the image file, and use application/pdf as the MIME type.

Community
  • 1
  • 1
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • Thanks. I changed the controller to accept a parameter identifying the file, then constructed the path and returned a FileResult. That had the desired effect of displaying the PDF. However, a user could still add the entire link in the browser and bring it up. I tried adding the location element to the web config as suggested by Charles but that didn’t do the trick (perhaps I did something wrong). I was able to get the desired effect however by adding a “deny” rule on that folder using IIS Manager. So now the user cannot display the PDF directly. – Jeff Rubingh Mar 04 '10 at 02:37
  • `However, a user could still add the entire link in the browser and bring it up.` -- That's why you add the Authorize attribute to the controller method, to restrict access to only those users that are assigned to the proper role. If the user types in an Url, access to which he is denied, he can be redirected to a Login or Unauthorized page instead of returning the `FileResult`. This is the same security you would add to *any* controller method to allow or deny access based on the user's assigned roles. More info here: http://nerddinnerbook.s3.amazonaws.com/Part9.htm – Robert Harvey Mar 04 '10 at 02:52
4

If you want to restrict all access to the /files directory you could simply use a location element in your web.config to restrict access.

E.g.

<location path="~/files">
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
</location>

I should add that I agree with Robert and Rob for advanced security, but if you just want a simple solution this should do the trick. :-)

HTHs,
Charles

Charlino
  • 15,802
  • 3
  • 58
  • 74
  • Doesn't restrict static files, they are handled by the StaticFileModule handler module, which doesn't use your authorization setup – Robert Benyi Nov 04 '19 at 11:12
1

Use FileResult, which I believe is a built-in ActionResult. This will send back binary data that you can have all kinds of authorization around:

http://msdn.microsoft.com/en-us/library/system.web.mvc.fileresult.aspx

0

If you used ASP.NET Core you can using Resource-based authorization

Authorization strategy depends upon the resource being accessed. Consider a document that has an author property. Only the author is allowed to update the document. Consequently, the document must be retrieved from the data store before authorization evaluation can occur.

Feri
  • 105
  • 1
  • 10