Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R Shiny authentication using AWS Cognito

I'm using R Studio Server in combination with R Shiny, running on an Ubuntu 16.04. Everything works fine. I want to secure the R Shiny dashboards (username+pw), and I'm thinking about building a small webpage that communicates with AWS Cognito to verify the users.

I can't find any documentation about this combination (Shiny + Cognito), but do find quite some documentation about both R Shiny Authentication (using NGINX + Auth0) and the use of Cognito (for example in combination with NodeJS).

Is a combination of Shiny and Cognito (with for example PHP or Node JS) logical and secure? What would be the best way to go: a simple web page with some PHP, or a Node JS application, with Shiny incorporated in it?

I realize this question is rather broad, but since I'm sure I'm not the only one walking around with this questions, I still ask so everyone can profit from possible solutions.

like image 662
Dendrobates Avatar asked Apr 19 '17 20:04

Dendrobates


People also ask

What is AWS Cognito authentication?

The Basics of Cognito Authentication Cognito is Amazon's cloud solution for authentication -- if you're building an app that has users with passwords, you can depend on AWS to handle the tricky high-risk security stuff related to storing login credentials instead of doing it yourself.

Does shinyproxy work with AWS Cognito?

For authentication, we will use AWS Cognito, a service provided by AWS that uses OpenID Connect protocol, which ShinyProxy also supports. For logging and monitoring, we will use InfluxDB, an open-source time-series database, to store the usage statistics from ShinyProxy.

Is it possible to deploy a shiny app on AWS EC2?

Following it, you should be able to deploy a functional Shiny app on AWS EC2 instance that can serve multiple users simultaneously. However, the app is not really production quality due to a couple of flaws.

What is the use case for using Cognito authentication?

Cognito is Amazon’s cloud solution for authentication – if you’re building an app that has users with passwords, you can depend on AWS to handle the tricky high-risk security stuff related to storing login credentials instead of doing it yourself.


1 Answers

Here is a description of the set-up I have implemented. This is using AWS Cognito along with AWS-specific features.

Context: I have a bunch of shiny apps, packaged in containers (typically using asachet/shiny-base or one of these Dockerfiles as a base). I want to host them privately and control who can access them.

The set-up below is an alternative to shiny-proxy. In fact, it does not need any kind of shiny server. Each app simply relies on shiny. Each of the containers exposes a port (e.g. EXPOSE 3838) and are simply launched with runApp(".", host="0.0.0.0", port=3838). The scaling policies take care of starting and stopping containers as needed. The authentication logic is completely decoupled from the app code.

My cloud set-up is:

  • An Application Load Balancer (ALB) is used as the user entry point. You must use an HTTPS listener to set up authentication. I simply redirect HTTP traffic to HTTPS.
  • A Elastic Container Service (ECS) task+service for each app. This makes sure my apps are provisioned adequately and run completely independently. Each app can have an independent scaling policy, so each app has the right amount of resource for its traffic. You could even configure the apps to automatically start/stop to save a lot of resources. Obviously, the apps need to be private i.e. only accessible from the ALB.
  • Each ECS has a different ALB target group, so requests to app1.example.com get forwarded to app1, app2.example.com to app2, etc. This is all set up in the ALB rules. This is where we can easily add authentication.

I have a Cognito "user pool" with user accounts allowed to access the apps. This can be used to restrict access to the app at the traffic level rather than the application level.

In order to do that, you first need to create a client app in your Cognito user pool. For app1, I would create a Cognito client app using the 'authorization code grant' flow with openid scope and app1.example.com/oauth2/idpresponse as the callback URL.

Once this is done, you can simply go into the ALB rules and add authentication as a prerequisite for forwarding:

ALB rule example

From now on, the traffic on app1.example.com must be authenticated before being forwarded to app1. Unauthenticated requests will be redirected to the Cognito Hosted UI (something like example.auth.eu-west-2.amazoncognito.com) to enter their credentials. You can customise what the hosted UI looks like in the Cognito settings.

Helpful links

For packaging R code in a container:

  • Rocker project and notes on extending an image
  • My personal Dockerfiles in particular shiny-base

For setting up Cognito authentication with an ALB:

  • Amazon documentation
  • Walk through: https://www.thorntech.com/2018/09/user-authentication-alb-cognito/ (which contains this video)
like image 188
asachet Avatar answered Oct 17 '22 04:10

asachet