Search code examples
authenticationnginxwebwebdav

NGINX make directory readonly unless authentication provided


I have a directory public, where I will upload various files. I want those files to be downloadable without any authentication. However, I also want to be able to edit and add new files using WebDAV, if authentication is provided. Is there any way I can have both behaviors on the same directory (location)?

I tried the following hack:

    location /public/ {
        if ($remote_user != "") {
            return 302 e;
        }
        auth_basic off;
        fancyindex off;
        dav_methods off;
    }

    location /public/e {
    }

However, I could not find a way to make /public/e index /public/ instead.

I also tried the following:

    location /public/ {
        if ($remote_user = "") {
            auth_basic off;
            fancyindex off;
            dav_methods off;
        }
    }

But Nginx complained that I cannot have those directives in an if-statement.

I also tried:

    location /public/ {
        set $authenticated off;
        if ($remote_user != "") {
            set $authenticated on;
        }
        auth_basic $authenticated;
        fancyindex $authenticated;
        dav_methods $authenticated;
    }

But Nginx said a variable is invalid, on or off was expected.

I also thought about making two directories, public and public-webdav, which are symlinked to the same directory, and assign different nginx locations to them, but I was hoping for a cleaner solution.

Thanks!


Solution

  • I solved it using this method:

    location @public {
        auth_basic off;
    }
    location /public/ {
        if ($remote_user = "") {
            error_page 418 = @public;
            return 418;
        }
    }
    

    That is, creating a custom handler for error 418 (teapot) and forcing that error.