Skip to content

Introduction

Paolo Cozzi edited this page Oct 31, 2025 · 5 revisions

Introduction

This project was born as an attempt to introduce an authentication step in front of the open-source version of shiny-server.

Some time ago, I made a first attempt by using HTTP Basic Authentication with docker compose with shiny and nginx. However, this solution was not ideal since HTTP Basic authentication is not secure even when using the HTTPS protocol. Moreover, there was no session between the browser and the server, making the authentication persistent until the browser is closed by the client. Closing and reopening the browser would require a new authentication, and this is the only way to use different credentials to access different restricted areas. Furthermore, credentials need to be managed only on the server side using openssl commands, which store credentials in an encrypted file and require that every restricted location is configured properly to check credentials against such file: this would be difficult to manage if there are different users with different access privileges. For these reasons, I searched for an alternative way to introduce an authentication process on top of the shiny server.

The idea was to introduce a session-based authentication process between the nginx and shiny layers, using a framework that can manage authentication relying on databases

After doing some research on the web, I found a clever solution in this tutorial made by pawamoy to implement authentication using the Django framework, so I decided to follow his guide and implement this version of django-server using docker compose. This project is not an attempt to replace the official Posit shiny products: it has limitations that the official enterprise software doesn't have. This project is an attempt to provide authentication on top of the community shiny server using only open-source solutions.

Shiny authentication alternatives

The official Posit solutions

Posit provides the enterprise version of the software made available to the community. They can support customers and provide additional features, for example the authentication layer is integrated natively and easy to configure. Updates are managed by the Posit team and shiny applications can scale up based on users' needs

  • shinyapps.io: This is the PaaS version of shiny server. Users can create accounts and upload their applications directly using Posit with the rsconnect package. There's a free plan for sharing up to 5 applications for a total of 25 hours of execution
  • Posit Connect: This is a platform that allows sharing of shiny applications, R Markdown, Jupyter notebooks, and more.

Community solutions

These are other solutions I found to add authentication to shiny applications. Maybe one of them could be useful to you:

  • polished: This is an R package that adds authentication to shiny applications relying on Firebase. More information can be found on their GitHub site and in this article on R bloggers
  • shinyproxy: This project adds authentication to shiny relying on Docker, Java, and Shiny. Its customization is very interesting since it can support LDAP authentication
  • shiny-user-auth: a simple shiny application that uses modals, Bootstrap, and SQLite to manage authentication with Shiny
  • using iframes: you could integrate shiny into an HTML document using iframes, as described in this Google group and in Posit community forums

Using Django for managing authentication

Django-based solutions

Django authentication can handle users, groups, permissions, and cookie-based user sessions. It provides tools for dealing with users, such as password reset or profile management. Moreover, Django adds some security features that make this framework reliable. Here are some attempts to manage shiny server using Django:

The pawamoy solution

In this guide, the author wraps the shiny server application using an iframe in a single Django view, and manages the subsequent websocket requests between the client and the shiny server using NGINX. By configuring NGINX to perform external authentication relying on the Django server, we can determine whether the client has access to the shiny websocket requests or not.

Enhance shiny authentication relying on Django models

Although the pawamoy solution addresses the main problem I have (adding an authentication layer to shiny), I needed to better structure this solution by adding the following features:

  • structure the project with docker-compose: this will ensure reproducibility in my testing and production environments, and I found it is easier to configure and manage compared to installing everything in a single Docker image or virtual machine
  • ensure authentication per application: relying on Django models and Django authentication, I want to grant access to individual applications, or define public applications (applications that don't require user authentication)
  • accessing applications directly (like the Shiny gallery does): in this way I can avoid the Django container itself and display the application on the whole page, while the authentication is handled behind the scenes
  • customize layout: structure the Django application views with Bootstrap

These features are implemented in the current shiny-server application project.

P.S. I've also written a medium post about this project, check it out, it's free!