Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Owin only serve files in certain folder

So I am playing around with Owin and Katana and I want to serve static files in my public folder.

I have a Content folder with stylesheets and a scripts folder.

My Startup:

    public void Configuration(IAppBuilder app)
    {
 #if DEBUG
        //when things go south
        app.UseErrorPage();
  #endif

        // Remap '/' to '.\public\'.
        // Turns on static files and public files.
        app.UseFileServer(new FileServerOptions()
        {
            RequestPath = PathString.Empty,
            FileSystem = new PhysicalFileSystem(@".\public"),
        });

    }

So if if I browse to localhost:8861/ I go the the index.html file in my public folder. That's ok. But I can also browse to my localhost:8861/Content/style.css which I want to block. Everything the user needs should be accessible in the public folder. All the rest should be blocked.

How can I achieve this?

like image 371
user1613512 Avatar asked Aug 27 '14 19:08

user1613512


2 Answers

If you need bare-bones file-handling, with absolute control over which files you do, or do not, want to serve you can take complete control with some middle-ware. I did this as I wanted uncached file-serving during development.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Web;

namespace Owin
{
    using AppFunc = Func<IDictionary<string, object>, Task>;

    public static class DynamicFileExtension
    {    
        /// <summary>
        /// ONLY use during development
        /// </summary>
        public static void UseDynamicFiles(this IAppBuilder app, string baseDirectory)
        {
            app.Use(new Func<AppFunc, AppFunc>(next => (async context =>
            {
                var method = (string) context["owin.RequestMethod"];
                var requestpath = (string) context["owin.RequestPath"];
                var scheme = (string) context["owin.RequestScheme"];
                var response = (Stream) context["owin.ResponseBody"];
                var responseHeader = (Dictionary<string, string[]>) context["owin.ResponseHeaders"];

                if (method == "GET" && scheme == "http")
                {
                    var fullpath = baseDirectory + requestpath;

                    // block logic...     

                    if (File.Exists(fullpath))
                    {

                        using (var file = File.OpenRead(fullpath))
                        {
                            await file.CopyToAsync(response);
                        }

                        var mime = MimeMapping.GetMimeMapping(fullpath);

                        responseHeader.Add("Content-Type", new[] {mime});

                        return;
                    }
                }

                await next.Invoke(context);
            })));
        }
    }
} 

I wouldn't use it in production, but it did the trick for me.

like image 173
Meirion Hughes Avatar answered Oct 16 '22 18:10

Meirion Hughes


The configuration of file server is correct and doesn't allow access to other folders. I've checked it within test OWIN self-host project and it works as expected, only public folder can be accessed. I assume that you use IIS to host your OWIN appllication (so your app is not self-hosted). If so, IIS Static File Handler allows aceess to static files and directories (and to your content folder as well). So you can search how to disable access to static files in IIS (can be done in web.config) or how to restrict access to some of them.

You can remove StaticFile Handler from website's configuration, but you should do it carefully because from this moment IIS won't serve static files at all.

<configuration>
    <system.webServer>
        <handlers>
           <remove name="StaticFile" />
        </handlers>
    </system.webServer>
</configuration>
like image 1
ntl Avatar answered Oct 16 '22 20:10

ntl