Media File Permissions.

Topics: Customizing Orchard, General, Writing modules
Sep 7, 2011 at 8:27 AM

HI,

I'm using a customised version of the 19ADocumentGallery, which stores documents in the media library.  What I'd like to be able to do is log every time a file is opened and check the current user for the roles they are in.

I was wondering how I can intersect the opening of that file before its streamed?

I was thinking of having a Module or something, using it a bit like a http handler to stream the doc, but that wouldn't work if they were to use the media library to embed a link to a file directly in a page - then it wouldn't work - unless I modified the media picker I guess.

Ideally I'd rather not write a new module for picking documents from the TinyMCE editor.  Maybe thats the only way - but if possible I'd like to avoid it.

Has anyone got any thoughts on this?  Looks to me like the file is simply accessed from the file system and no code is executed?

Thx in advance.

Steve

Coordinator
Sep 7, 2011 at 4:33 PM

Do you want the verification to happen when a request is done from a client to the file, or when a user tries to pick a file using the media picker ?

Sep 8, 2011 at 10:05 AM

Most important is when a request is done from a client to the file.

Is there a way I can do that?

Coordinator
Sep 8, 2011 at 7:23 PM

You can create a moudle which will register a generic route for the Media folder, then your control will be called, and you can check anything in here, return a FileResult or HttpUnauithorizedResult.

Sep 9, 2011 at 9:24 AM

Hi, thanks for your reply....

I'm not sure what I'm doing is correct or along the right lines...either way its not working!!

I've created a Routes.cs file at the route of my project...in debug the GetRoutes() is hit.

I've also got a HomeController.cs with an Action method GetDoc()

This is what I've got in the route:

public class Routes : IRouteProvider {
        public void GetRoutes(ICollection<RouteDescriptor> routes) {
            foreach (var routeDescriptor in GetRoutes())
                routes.Add(routeDescriptor);
        }

        public IEnumerable<RouteDescriptor> GetRoutes() {
            return new[] {
                new RouteDescriptor {
                    Priority = 1,
                    Route = new Route(
                        "Media",
                        new RouteValueDictionary {
                            {"area", "Percy.MediaPermissions"},
                            {"controller", "Home"},
                            {"action", "GetDoc"}
                        },
                        new RouteValueDictionary(),
                        new RouteValueDictionary {
                            {"area", "Percy.MediaPermissions"}
                        },
                        new MvcRouteHandler())
                }
            };
        }
    }

What do you think?

Sep 14, 2011 at 10:32 AM

Anyone have an idea on this one?

I cant seem to stop the media file just being streamed directly?

I've tried the above and this?

public IEnumerable<RouteDescriptor> GetRoutes()
        {
            return new[] {
                new RouteDescriptor {
                    Priority = 1,
                    Route = new Route(
                        "Admin/Media/Default/{*path}",
                        new RouteValueDictionary {
                            {"area", "Percy.MediaPermissions"},
                            {"controller", "Home"},
                            {"action", "GetDoc"}
                        },
                        new RouteValueDictionary(),
                        new RouteValueDictionary {
                            {"area", "Percy.MediaPermissions"}
                        },
                        new MvcRouteHandler())
                }
            };
        }

Sep 14, 2011 at 10:56 AM
Edited Sep 14, 2011 at 11:22 AM

I've got a LoginRequired Filter attribute and just noticed that doesnt get hit when putting the url in directly for a media files.

This is a pretty big concern considering my site is supposed to be restricted?

Please help.

 

public class LoginRequiredFilter : Orchard.Mvc.Filters.FilterProvider, IAuthorizationFilter
    {
        private readonly IAuthorizer _authorizer;

        public LoginRequiredFilter(IAuthorizer authorizer)
        {
            _authorizer = authorizer;
            T = NullLocalizer.Instance;
        }

        public Localizer T { get; set; }

        public void OnAuthorization(AuthorizationContext filterContext)
        {

 

As a note:

If I type in the URL

/Media/Default/123/123.pdf ... my new route is hit and sent to the correct place with "123/123.pdf" in the path... but with a real MediaPath after it...nothing??

It would appear that the url directly to a file takes priority over everything?  If I have the an url to a file that does not exist...my route fires?

Where can I set RouteExistingFiles to true in Orchard and only make it route ones for specific folders?

Coordinator
Sep 14, 2011 at 9:13 PM

You might want to check on the IIS side, that those extensions are actually going through the managed pipeline.

Sep 14, 2011 at 9:44 PM
But without setting RouteExistingFiles every file that is on disk will bypass the asp.net pipeline.

I've kind of got something working, setting the above flag and adding in wildcard bypass for certain extensions...like CSS, js etc that I don't want to intersect.
I've put that in Global, but I'd like to if poss deploy it as part of a module. Is there a way I can hook into the app startup and add the RouteExistingFiles flag to true and add the ignore routes to the table?

Thx

On 14 Sep 2011, at 22:13, "bertrandleroy" <notifications@codeplex.com> wrote:

From: bertrandleroy

You might want to check on the IIS side, that those extensions are actually going through the managed pipeline.

Coordinator
Sep 23, 2011 at 1:02 AM

I don't think so.

Jul 10, 2013 at 1:47 AM
Correct me if I'm wrong; but can some of this just be accomplished by adding <authorization><deny users="?"/></authorization> to the web.config in the Media folder, instead of going through the trouble of writing a route? (If we don't need specific role checks, but just authenticated access to those files only)