RareBoy
RareBoy

Reputation: 77

asp.net MVC secure root folder only for authorized users

I am having this small extranet service where users can log in, get all sorts of info and download few files.

Is it possible to secure root folder in MVC asp.net project? I am having a project where users have to log in before using any material. How ever if I use for example "/material" folder for every pdf, jpg, etc. files, other unauthorized users can see those files also.

For example everybody can see this file if they type www.example.com/material/pdf-file.pdf So I want only authorized / logged users to see this file. Is this possible?

Upvotes: 0

Views: 1585

Answers (2)

kayess
kayess

Reputation: 3394

It's possible to do that, but there are a lot ways to accomplish that.

A simplified scenario could be:

  • Disable directory listing on IIS
  • Create a custom "download wrapper" controller+action for the purpose of serving of those files.
  • Then wherever you create Action links, generate them using a HtmlHelper which would redirect the client to the "wrapper" controllers action. You can pass the filename in a parameter.
  • On the "wrapper" controller you could utize the [Authorize] attribute or better yet, without using such attributes everywhere you could use FluentSecurity for handling the authorization.

After you create the "wrapper" controller your URL for getting a file could look like:

www.example.com/download/file/pdf-file.pdf

This example URL assumes controller name is 'download' and action name is 'file'.

Upvotes: 0

RareBoy
RareBoy

Reputation: 77

I managed to get it work. Here is how I did it.

The first I added this line to Web.config file:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">

This allows dot chars in .pdf, .png, etc... in url's.

I added to RouteConfig.cs new routing for controller.

routes.MapRoute(
            name: "Material",
            url: "Material/Download/{file}",
            defaults: new { controller = "Material", action = "Download", file = UrlParameter.Optional }
        );

I created a new controller "Material".

// GET: Material
    [Authorize]
    public ActionResult Download(string file)
    {
        string path = Server.MapPath(String.Format("~/App_Data/Material/{0}", file));

        if(System.IO.File.Exists(path))
        {
            string mime = MimeMapping.GetMimeMapping(path);

            return File(path, mime);
        }

        return HttpNotFound();
    }   

And also transfered material folder inside app_data.

This seems to work nicely. Only authorized users can access to material folder.

Upvotes: 2

Related Questions