39

I want to publish an R Shiny web application (http://www.rstudio.com/shiny/) on the web, but I want to password protect it so that only people with credentials can view what I have published. What is the best way to do this ?

Nicholas Hamilton
  • 10,044
  • 6
  • 57
  • 88
  • 1
    There is an open source alternative now to deploy Shiny apps: http://www.shinyproxy.io It seems to support LDAP out of the box. – pauljeba Jul 18 '16 at 06:15
  • 1
    I followed this tutorial to use apache as a gatekeeper: https://www.r-bloggers.com/password-protect-shiny-apps/. You have to read all 4 tutorial pages carefully. Also, it helped me to use the `sanitize_errors=false;` in the shiny-server.conf file. – Paul Dec 30 '16 at 16:40
  • Here is a tutorial (from me) with an already setup Docker project: http://pawamoy.github.io/2018/03/15/django-auth-server-for-shiny/. It uses NginX and auth-request module. – pawamoy Mar 15 '18 at 14:05

7 Answers7

24

This might be a little late but I am going to answer anyways. If you have already got a solution, can you please share it with us?

My primary aim was very simple. I had a working version of shiny app on my laptop. I used to run it as mentioned below, all the while for testing locally.

R -e "shiny::runApp('.')"

Then came the moment when we had to put this on out on an Amazon EC2 instance.

At first my attempt was to directly proxy apache to port 8100 on which my app would listen to. But that didn't work that well as it appears that running the server in this manner actually uses raw sockets where as using a shiny-server falls back to using sock.js hence the communication is now over HTTP instead.

So downloaded the shiny-server app on our EC2 instance by following the instructions here: https://github.com/rstudio/shiny-server

Btw, though the instructions there recommend you install node.js from source if you are using a RHEL instance, it worked pretty well for me by going the yum install way. You have those instructions here.

Following the node.js, shiny-server installation & setup, edited my Apache conf (Ubuntu and RHEL call the conf differently. Hence edit the one you have). Added a virtual host to service my requests. And as you can notice, also masked it with a Apache Basic digest Auth with the Apache Location directive.

<VirtualHost *:80>

    ProxyPass / http://localhost:3838/
    ProxyPassReverse / http://localhost:3838/
    ProxyPreserveHost On

    <Location />
        AuthType Basic
        AuthName "Restricted Access - Authenticate"
        AuthUserFile /etc/httpd/htpasswd.users
        Require valid-user
    </Location>

</VirtualHost>

Apart from this also edited the shiny-server conf to listen to request from 127.0.0.1 only (localhost only). So in my shiny-server I have the following:

listen 3838 127.0.0.1;

Btw, you wouldn't need this if you are in an Amazon EC2 environment as you can use the security-group setting in your EC2 dashboard to do the same. I did this anyway as a good measure.

This, for now, is enough as we were looking for something very quick & simple.

Now desperately waiting for the awesome RShiny folks to provide auth as a part of the enterprise edition deal.

Hope this helps.

shingav
  • 462
  • 3
  • 10
  • I Rohith, i tried this but am getting 401s when shiny attempts to open the websocket. Does the browser pass the authentication credentials for /websocket correctly? Was there another module to install that got this working? – justinvf Jan 02 '14 at 00:38
  • Well, the idea here is that Shiny is totally disconnected from the authentication logic. Here we completely rely on the Basic Digest authentication provided by Apache and let Apache do a simple redirect to the Shiny app once apache confirms the auth. So all of Shiny & websockets are simply hiding behind this Apache layer. So if there is a Shiny specific error, I suggest you look up your Shiny conf (which I think is in /etc/shiny-server/shiny-server.conf on Ubuntu) and do a Shiny related debugging than look at Apache at all. – shingav Jan 03 '14 at 04:34
  • Thanks. This was a fairly simple solution. – Cerin Feb 28 '14 at 22:44
  • Hi, I'm trying to follow this but can't get the authentication to show up. Any advice? Do you still need TCP 3838 as allowed in Amazon? If I remove it then nothing happens whatsoever-- it just spins.. – user1357015 Aug 30 '15 at 06:54
  • If you aren't getting the apache auth pop-up to show up, could it then be a configuration issue with Apache than to do with the plumbing of RShiny with Apache? – shingav Nov 15 '15 at 08:16
10

This may be a little late for the OP but it may be useful for your use case:

https://auth0.com/blog/2015/09/24/adding-authentication-to-shiny-open-source-edition/

It's similar to the Rohith's answer, but it uses Auth0 instead, which allows you more authentication options (Like connecting, Google Accounts, Active directory, LDAP, and a big etc)

Disclaimer: I work at Auth0, we are using Shiny internally with this configuration and it works fine.

Sicarul
  • 149
  • 1
  • 6
5

A little bit later (2016), but I've found another option using ngnix as a proxy:

This guide has been finished by following partially this guideline: https://support.rstudio.com/hc/en-us/articles/213733868-Running-Shiny-Server-with-a-Proxy

On an Ubuntu 14.04:

  1. Install nginx
  2. Change file config /etc/nginx/nginx.conf to:

This:

events {
        worker_connections 768;
        multi_accept on;
}

http {

  map $http_upgrade $connection_upgrade {
      default upgrade;
      ''      close;
    }

  server {
    listen XX;



    location / {
      proxy_pass http://localhost:YY;
      proxy_redirect http://localhost:YY/ $scheme://$host/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_read_timeout 20d;

      auth_basic "Restricted Content";
      auth_basic_user_file /etc/nginx/.htpasswd;
    }
  }
}

XX: Port that the nginx will listen to

YY: Port that the shiny server uses

  1. Using this tutorial, I added password authentication to the nginx server: https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-14-04

  2. Set up the shiny process or the shiny server to only listen to localhost (127.0.0.1)

Geiser
  • 1,054
  • 1
  • 12
  • 28
  • 1
    This is a great post that sums up the entire setup method using nginx in one concise block of code (at the end of the post): https://www.r-bloggers.com/shiny-server-on-aws/ – Paul Jan 14 '17 at 21:41
2

This could be viewed as an HTTP requirement rather than a Shiny feature. If so, you could look into first implementing an HTTP authentication, and once the credentials are verified, you can redirect to your Shiny app URL.

Searching SO or the Web for basic authentication should get you a few useful links and get you closer.

Ram Narasimhan
  • 22,341
  • 5
  • 49
  • 55
  • 1
    It isn't quite that simple. Shiny apps run on their own application server (Shiny-server), so it's not as simple as plodding in a few lines in an existing httpd.conf... Answer above covers the details :-) – andy Sep 25 '13 at 21:52
1

At this time there isn't a straight forward way to do this. However we will be releasing a commercial version of Shiny Server in the near future. We'll be doing a beta in the upcoming month or so and the official release before the end of the year. This will include the ability to have password authentication for your Shiny Apps. In addition, Shiny Server Pro will have features around security, authentication, scalability, server monitoring, and premium support.

Another place that you might be able to get some feedback is the Shiny Mailing List. There are a lot of active users who might have some ideas. Otherwise, if you'd like to contact us directly about this, you can email info@rstudio.com and I'll respond.

Best,

Josh

Product Manager - RStudio

Josh Paulson
  • 527
  • 5
  • 6
1

Its too late for the answer but I think, there is development around the same. You can use google auth to login in the shiny web apps. There is a solution on different thread, you can refer that : ShinyApp Google Login

  • 1
    If you would like to contribute this as an answer, please make it standalone so that future readers don't have to rely on this link. It's great to use sources as a reference for your answer, but do ensure that your answer makes a contribution to the question. – dspencer Mar 16 '20 at 02:45
0

We have implemented the solution with multi-level authentication:

  1. Using query string based values for application to load

    • Time based Encrypted token to expire at certain point in future
    • User name (used in next auth step)
  2. Modal dialog to validate access code

    • Validated against AES encrypted value of user name

Reference: CRAN - digest -> AES used CBC mode for both levels with Encryption Key (32 Byte raw vector) and IV of long length

shyam
  • 537
  • 6
  • 16