Open source version of shiny server does not include any authorization option so if you want to limit access based on login you have to use either Apache or nginx as “reverse proxy”. We choose nginx because it is very simple and elegant solution which not requires any complicated stuff.

We started with basic configuration but over time we had several different problems so currently we have this config file (nginx runs in separate container therefore there is “set $target_host” command):

 

# authorization check
map $http_authorization $is_auth_proxy {
    default 0;
    "Basic ........." 1; # user/pass ## here put login:password
}

server {
    listen 80; ## listen for ipv4e
    server_name shiny.proxy.ourweb.com;
    client_max_body_size 0;

    location / {
        resolver 8.8.8.8;
        set $target_host "xxx.xxx.xxx.xxx:80";
        client_max_body_size 0;

        if ($is_auth_proxy != 1) {
          # uncomment next line to enable auth dialog in browsers
            add_header 'Www-Authenticate' 'Basic realm="Our Shiny Apps"' always;

            return 401;
        }

        proxy_set_header 'Authorization' ''; # do not pass auth headers
        proxy_pass http://$target_host$uri$is_args$args;

        proxy_buffering off;
        proxy_request_buffering off;
        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Origin "";
    }

    error_page   500 502 503 504  /50x.html;

    location = /50x.html {
        root   html;
    }
}

Biggest issue we had was with failing websocket connections – shiny server log showed error messages like this one – “[2018-xx-xxTxx:xx:42.066] [WARN] shiny-server – RobustSockJS collision: YVDVBxxxxxxHncCxxx” and nginx logs contained a lot of buffering errors (“2018/06/07 08:52:44 [warn] 7#7: *19 a client request body is buffered to a temporary file /var/cache/nginx/client_temp/0000000004, client: xxx.xxx.xxx.xxx, server: shiny.proxy.ourweb.com, request: “POST /our_app/__sockjs__/o=YVDVB6pna1JHncCj6m/309/gqava3qy/xhr_send HTTP/1.1”, host: “shiny.proxy.ourweb.com”, referrer: “http://shiny.proxy.ourweb.com/our_app/”

Solution was combination of these two issues and necessary settings are already in the example above: