Comment protéger votre application Shiny avec un mot de passe

Cet article fait partie de la série Comment déployer une application Shiny sur AWS, divisée en 7 parties. Pour accéder aux autres parties, utilisez le sommaire ci-dessous:


On arrive à la dernière partie de cette série d’articles !

Cette fois-ci, on va apprendre à protéger notre application derrière un portail d’authentification.

La plupart des applications Shiny que j’ai eu l’occasion de créer pour mes clients étaient des applications internes.

Ça veut dire qu’on utilise des données de l’entreprise, confidentielles, et le dashboard est utile à une équipe en particulier. Mais ce n’est pas fait pour être ouvert au grand public.

Dans certaines entreprises, on dispose d’un réseau interne, parfois d’un VPN, et alors c’est facile d’isoler le dashboard de l’internet public.

Mais parfois, ce n’est pas possible.

Ou alors, on veut donner l’accès à un public plus large, et on veut pouvoir gérer des utilisateurs et des droits d’accès.

Les besoins sont multiples.

Dans cet article, on va voir comment répondre à ces besoins, du plus simple au plus complexe :

  1. Comment mettre un mot de passe unique avec nginx
  2. Comment utiliser un service tiers comme auth0
  3. Comment créer votre propre portail d’authentification maison

Avant de commencer, j’aimerais ajouter un petit avertissement.

Dans cet article, on va parler sécurité. Je ne suis pas un expert en sécurité informatique, c’est un vrai métier et ce n’est pas le mien.

Vous restez responsable de la sécurité de vos applications.

Cet article est purement informatif.

À présent que ceci est précisé, allons-y !

Les choix possibles

Dans un premier temps, je vais vous présenter succinctement les choix à votre disposition. Je vais ensuite décrire comment mettre en place chacun d’eux.

En gros, vous avez le choix entre :

Utiliser Shiny Server Pro

Haha.

Je plaisante.

Utiliser votre serveur web nginx

Shiny AWS create application

Dans les précédents articles, on a utilisé nginx comme reverse proxy.

nginx agit comme un gardien à l’entrée du serveur et redirige les visiteurs vers le bon service, comme notre Shiny Server en l’occurrence.

Une étape supplémentaire logique serait d’utiliser ce gardien pour autoriser ou refuser certains visiteurs.

Plutôt que de laisser passer tout le monde, il pourrait demander un mot de passe aux visiteurs et ne donner l’accès qu’à ceux disposant d’identifiants valides.

C’est une solution qui marche très bien, qui est très facile à mettre en place, et qui offre en plus une bonne sécurité puisqu’une partie du code de l’application n’est pas chargée tant qu’on n’est pas authentifié.

Utiliser un service tiers comme auth0

Shiny AWS create application

auth0, c’est une surcouche d’authentification que vous pouvez intégrer dans n’importe quelle application.

Vous le mettez en place, et c’est lui qui se chargera de gérer les utilisateurs et les droits d’accès.

C’est gratuit jusqu’à 7000 utilisateurs (pas mal !).

Et l’outil s’intègre automatiquement avec Shiny.

Le gros avantage, c’est que vous n’avez pas à vous soucier de la sécurité.

Ce sont eux qui s’en occupent, c’est leur spécialité, donc on peut imaginer qu’ils font ça mieux que nous.

Maintenant, ça reste un service tiers, ce qui crée une dépendance pas toujours désirable.

Utiliser une solution maison

Shiny AWS create application

Finalement, la dernière alternative que je vous propose : le faire vous-même.

Si vous êtes arrivé jusqu’ici dans cette série d’articles, c’est que vous aimez quand même un peu vous faire du mal faire les choses par vous-même.

Il est important de noter toutefois que cette solution est celle qui apporte le moins de sécurité, puisque vous n’êtes pas un expert en sécurité, et moi non plus.

En plus, on ne sait pas trop si Shiny sécurise correctement les données ou non.

Imaginez par exemple que vous ajoutiez un portail d’authentification au début de votre appli Shiny.

Et ensuite, vous écrivez dans le code quelque chose du genre : « Si l’utilisateur se login, on montre le reste de l’application. »

Du coup, ça implique d’accéder au Shiny Server pour pouvoir se logger.

Mais est-ce que le reste du code est caché tant qu’on n’est pas loggé ?

Est-ce qu’il n’y a pas moyen de manipuler la console Javascript ou une autre backdoor pour accéder aux données ?

Est-ce que votre formulaire d’authentification est résistant à l’injection SQL ?

Les réponses à ces questions restent un peu floues, et même si on s’assure de pouvoir répondre à certaines, on ne sera jamais sûr à 100% d’avoir tout sécurisé correctement.

De mon point de vue, le gros problème, c’est qu’on a accès au Shiny Server pour pouvoir se logger. On charge déjà du code Shiny.

Dans la solution du serveur nginx, par exemple, le Shiny Server n’est pas accessible tant qu’on n’a pas passé l’étape d’authentification.

Et c’est généralement une bonne pratique de séparer le serveur d’authentification (le rôle que joue nginx par exemple) et le serveur applicatif.

Mélanger les deux, c’est chercher des ennuis.

Donc cette solution est très bien si vous voulez restreindre l’accès sans avoir une sécurité au top level.

Elle est relativement simple à mettre en place, d’autant plus que vous connaissez déjà Shiny, donc c’est très flexible si vous voulez créer des comptes admin, gérer des droits utilisateurs, etc. Ce que ne permet pas nginx.

Mais gardez en tête que faire appel à un vrai professionnel de la sécurité peut être une bonne idée aussi.

À présent, je vais détailler chacune de ces solutions.

Utiliser nginx comme serveur d’authentification

Cette solution est la plus simple à mettre en place, mais est aussi la moins flexible.

En gros, vous allez d’abord choisir et enregistrer les logins et mots de passe au niveau du serveur.

Ensuite, vous aurez un popup pas très accueillant à chaque connexion.

C’est un peu la solution rapide et pas chère.

Mais c’est très efficace si vous avez une appli que vous voulez montrer seulement à certaines personnes.

Par exemple, quand vous développez une application pour un client et que vous voulez lui montrer sans la rendre accessible au grand public. Généralement, le plus simple est de la mettre sur votre serveur, de paramétrer un mot de passe et de la partager à votre client.

De nouveau, on va devoir mettre les mains dans notre serveur et sa console.

D’abord, les prérequis : vous devez avoir suivi les deux articles précédents :

Vous devriez avoir un fichier de config (celui qui se trouve à /etc/nginx/sites-available/shiny.conf) qui ressemble à ça (à quelques détails près) :

server {
    listen 80;
    listen [::]:80;
    server_name shiny.charlesbordet.com;
    server_tokens off;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    root /dev/null;
    server_tokens off;
    client_max_body_size 0;

    server_name shiny.charlesbordet.com;

    access_log /var/log/nginx/shiny-access;
    error_log /var/log/nginx/shiny-error;

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

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /etc/letsencrypt/live/shiny.charlesbordet.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/shiny.charlesbordet.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;

    # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
    ssl_dhparam /etc/nginx/dhparam.pem;

    # intermediate configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;

    # verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /etc/letsencrypt/live/shiny.charlesbordet.com/chain.pem;
}

C’est un gros fichier qui fait un peu peur, mais comme on y est allé petit à petit, il ne fait pas si peur que ça.

Bon maintenant, on va devoir rajouter un nouveau bloc location qui est quasiment identique à celui qui existe déjà mais avec deux petites différences :

  1. D’abord la location en tant que telle ne sera plus à la racine (c’est-à-dire /) mais sur le dossier /movie-explorer.
  2. Et ensuite, on va rajouter de quoi mettre un mot de passe.

Voici à quoi ressemble le nouveau bloc que vous pouvez ajouter juste en dessous de l’autre :

location /movie-explorer {
    proxy_pass http://localhost:3838;
    proxy_redirect http://localost:3838/ $scheme://$host/;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_read_timeout 20d;
    proxy_buffering off;
    auth_basic "Restricted Content";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

Pourquoi rajouter une location ?

En fait, on pourrait seulement rajouter les deux lignes suivantes au précédent bloc location :

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

Sauf que dans ce cas, toutes vos applications Shiny seront protégées par les mêmes mots de passe.

Ce n’est pas forcément ce qu’on veut.

On peut vouloir avoir certaines applications protégées, et d’autres accessibles.

Là, ça permet de choisir.

Enregistrez le fichier.

Maintenant, on va devoir remplir le fichier /etc/nginx/.htpasswd avec les identifiants.

C’est très simple. D’abord, lancez cette instruction pour créer l’identifiant :

$ sudo sh -c "echo -n 'charles:' >> /etc/nginx/.htpasswd"

Vous pouvez remplacer charles par le login que vous voulez.

Ensuite, la commande suivante vous permet d’entrer un mot de passe et de le stocker de manière chiffrée. On ne stocke jamais un mot de passe en clair ! :

$ sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd"

Et voilà !

Vous pouvez répéter l’opération autant de fois que nécessaire pour créer davantage de combinaisons login & mot de passe.

À présent, on redémarre le serveur nginx :

$ sudo nginx -t
$ sudo systemctl restart nginx

Et maintenant, votre application va être protégée.

Vous pouvez essayer mon application à l’adresse https://shiny.charlesbordet.com/movie-explorer-secure/ et vous remarquerez qu’une fenêtre d’authentification s’affiche.

Pas d’identifiant ? Pas d’accès.

Essayez avec :

  • login = guest
  • mot de passe = trololo

Et vous devriez pouvoir accéder à l’application !

Notez que bien que cette technique soit plutôt bien sécurisée, il faut absolument forcer le passage par nginx pour que ça marche.

Donc bloquez le port 3838 avec votre pare-feu (celui de AWS suffit, ou bien utilisez ufw).

Notez aussi que vous n’êtes pas protégé face à une attaque de type bruteforce.

Un mot de passe de seulement 8 caractères se casse en quelques secondes.

Donc soit vous utilisez des mots de passe plus longs, soit vous passez par l’outil fail2ban pour bannir les adresses IP qui font plusieurs tentatives de login infructueuses.

Maintenant, bien que cette technique soit très facile à mettre en place et offre une bonne sécurité, tout n’est pas parfait.

D’abord : C’est compliqué de créer de nouveaux comptes.

On n’a pas d’interface, il faut passer par le serveur, etc. On a vu plus simple.

Et puis, ça ne s’automatise pas facilement.

Ensuite : Ce n’est pas franchement convivial.

Franchement vous verriez un site e-commerce utiliser une fenêtre moche comme ça pour donner accès à un compte client ?

Non.

Et enfin : Ça ne répond pas à tous les besoins.

C’est soit on accède, soit on n’accède pas. Pas de gestion de compte ni de droits d’accès. On ne peut même pas savoir quel login a été utilisé pour accéder à l’application Shiny.

Du coup…

On peut essayer autrement.

Utiliser auth0 comme serveur d’authentification

Cette deuxième solution est un peu plus compliquée à mettre en place, mais elle a de gros avantages :

  • Sécurité optimale
  • Gestion d’utilisateurs
  • Simplicité

Auth0 est un fournisseur de services d’authentification et d’autorisation.

Plutôt que de créer nous-même une application d’authentification, Auth0 va s’en charger à notre place via un SDK (ou un appel à leur API).

Mettre en place Auth0

Première étape : Créer un compte Auth0.

Naviguez sur https://auth0.com/signup et créez un compte.

Vous pourrez utiliser le service gratuitement jusqu’à un maximum de 7000 utilisateurs.

Une fois le compte créé, connectez-vous et cliquez sur le gros bouton CREATE APPLICATION :

Shiny AWS create application

Donnez-lui un nom puis choisissez Regular Web Applications :

Shiny AWS create application

Vous ne trouverez pas Shiny dans les applications proposées par défaut, donc on va devoir configurer notre portail manuellement. Cliquez sur Settings

Les informations importantes à noter sont :

  • Domain
  • Client ID
  • Client Secret

On en aura besoin un peu plus tard.

Un peu plus bas, dans la case Allowed Callback URLs, vous devez remplir votre URL suivi de callback. Donc pour moi, j’ai rempli https://shiny.charlesbordet.com/callback.

Attention : Pas de slash / à la fin !

À présent, vous pouvez enregistrer les changements.

Maintenant, il va falloir installer le portail d’authentification sur votre serveur. Connectez-y vous via SSH, comme d’habitude, puis effectuez les étapes suivantes :

1. Installez NodeJS

$ sudo apt update
$ sudo apt install curl
$ curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
$ sudo apt install nodejs

2. Installez l’application de Auth0

$ git clone git@github.com:auth0/shiny-auth0.git
$ cd shiny-auth0
$ npm install

3. Paramétrez

Il ne reste plus qu’à paramétrer l’application Auth0 pour que le service utilise les paramètres que vous avez créé tout à l’heure dans votre compte !

Créez un fichier nommé .env (en tapant par exemple nano .env) et remplissez-le des informations suivantes :

AUTH0_CLIENT_SECRET=votreClientSecretAuth0
AUTH0_CLIENT_ID=votreClientIDAuth0
AUTH0_DOMAIN=votreDomainAuth0
AUTH0_CALLBACK_URL=https://shiny.charlesbordet.com/callback
COOKIE_SECRET=r7QVJVVxj77CJyuX5tGrE238uLGGh8XZb84c3WdvWgQ5RPVwYc
SHINY_HOST=localhost
SHINY_PORT=3838
PORT=3000

Pour les quatre premiers, ce sont les informations qu’on a récupérées tout à l’heure dans votre compte Auth0.

Le COOKIE_SECRET doit être une longue chaîne de caractères aléatoires. J’ai utilisé un générateur de mots de passe pour ça.

Ensuite, laissez ce qui reste tel quel.

Pour l’instant, notre application Shiny n’est toujours pas sécurisée.

En effet, Shiny écoute sur le port 3838, tandis que le portail d’authentification est une autre application qui écoute sur le port 3000.

Or, avec nginx, on dit de rediriger https://shiny.charlesbordet.com vers le port 3838. Donc on court-circuite le portail d’authentification !

Comment résoudre ce problème ?

Eh bien tout simplement en disant à nginx de rediriger directement vers le port 3000 et de ne pas donner l’accès direct au port 3838.

Pour ça, il suffit de changer les instructions proxy_pass et proxy_redirect dans votre fichier de configuration nginx :

proxy_pass http://localhost:3000;
proxy_redirect http://localhost:3000/ $scheme://$host/;

Puis on enregistre la configuration :

$ sudo nginx -t
$ sudo systemctl restart nginx

Si vous essayez à présent d’accéder à votre application, ça ne va plus fonctionner. C’est parce que nous n’avons pas démarré le portail d’authentification.

Pour ça, rendez-vous dans le dossier shiny-auth0 et lancez la commande suivante :

$ cd /home/charles/shiny-auth0
$ node bin/www

Vous remarquerez que la console n’affiche rien et vous n’avez plus la main.

En effet, la commande qu’on a écrite permet de démarrer l’application du portail d’authentification mais c’est un démarrage manuel. C’est pourquoi on n’a plus la main.

On peut néanmoins tester si le portail fonctionne.

Connectez-vous sur votre application Shiny. La fenêtre suivante devrait s’afficher :

Shiny AWS create application

Vous pouvez créer un compte, vous logger, puis accéder à l’application.

Pour reprendre la main dans la console, vous pouvez arrêter Auth0 avec Ctrl + C.

Super mais bon… Il reste quand même deux problèmes :

  1. Ce démarrage manuel est un peu bizarre. Il faudrait qu’on garde toujours la console ouverte ?
  2. Le but est de limiter l’accès, pas d’offrir la possibilité à n’importe qui d’ouvrir un compte !

On va s’en occuper.

Créer un service pour Auth0

On a déjà des “serveurs web” sur notre machine :

  • Shiny Server, qui est un serveur web qui écoute sur le port 3838.

  • nginx, qui est aussi un serveur web qui écoute sur le port 80.

Et là, Auth0 est un autre serveur web qui écoute sur le port 3000.

Alors pourquoi doit-on lancer Auth0 manuellement, et pas les autres ?

La raison : les autres sont des services. C’est-à-dire qu’ils sont lancés automatiquement dès le démarrage de la machine. Et la configuration du service a été automatique dès l’installation de ces serveurs web.

Pour Auth0, on va devoir créer manuellement le service, et tout sera ensuite automatique.

Pour ça, ce n’est pas très compliqué, vous allez simplement créer un nouveau fichier :

$ sudo nano /etc/systemd/system/shiny-auth0.service

Et ce fichier va contenir les informations suivantes :

[Service]
ExecStart=/usr/bin/node /home/charles/shiny-auth0/bin/www
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=charles
User=charles
Group=charles
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

Assurez-vous bien de remplacer le nom d’utilisateur charles par le vôtre !

En général, la bonne pratique est de créer un nouveau nom d’utilisateur spécifiquement pour chaque service (comme l’utilisateur shiny qui a été créé automatiquement pour le Shiny Server).

Grâce à ça, si le service est compromis, le reste du serveur n’est pas atteint.

Une fois cette configuration faite, il ne reste plus qu’à activer le service :

$ sudo systemctl enable shiny-auth0
$ sudo systemctl start shiny-auth0

À présent, votre portail d’authentification est en ligne, plus besoin de démarrage manuel !

Maintenant, l’autre problème : comment restreindre l’accès ?

Créer des règles de restriction

Pour cette partie-là, tout se passe dans l’interface de votre compte Auth0.

Vous aurez peut-être remarqué la section “Rules”, qui permet de créer des règles à l’aide de petits snippets Javascript. Après avoir cliqué sur CREATE RULE, vous accédez à plein de possibilités :

Shiny AWS create application

Vous pouvez par exemple :

  • Spécifier la liste des emails autorisés,
  • Interdire d’utiliser les Google, Facebook et cie pour créer un compte,
  • Vous connecter à une API pour vérifier si l’utilisateur est autorisé,
  • et créer vos propres règles personnalisées.

Je vous avoue que cette partie est un peu intimidante pour moi. Ma connaissance en Javascript reste très limitée, donc je préfère en rester aux règles pré-configurées.

Par exemple, pour un client qui veut que son appli ne soit accessible qu’à ses employées, limiter l’inscription aux emails du type xxx@nomdelentreprise.com est déjà très pratique !

D’un autre côté, le fait de pouvoir directement écrire les règles en Javascript rend le système de règles super flexible.

On peut très bien imaginer par exemple que vous vendiez votre application Shiny comme un produit SaaS, l’acheteur est ajouté à votre Mailchimp sur une liste spécifique, et votre règle utilise l’API de Mailchimp pour autoriser l’accès seulement aux acheteurs de cette liste.

D’ailleurs, l’inverse est aussi possible. Par exemple, l’accès à votre application Shiny est gratuite mais nécessite la création d’un compte. Puis les informations de ce compte sont automatiquement exportées vers Mailchimp pour que vous puissiez communiquer avec les utilisateurs.

Ça demande simplement un peu de Javascript.

Pour nous autres développeurs de Shiny, connaître un peu de Javascript ne peut pas faire de mal !

En tout cas, ce service Auth0 fait plutôt bien le job.

Mais pour ma part, je ne me vois pas trop l’utiliser, sauf dans des cas très spécifiques (comme les exemples que je viens de citer).

En fait :

  • Je n’aime pas trop que ça utilise NodeJS. Je ne connais pas du tout cette techno, et l’inconnu me fait peur.
  • Utiliser un service tiers me rend dépendant. Et si demain Auth0 décidait de changer les règles ?
  • Bien que le système de règles soit flexible, le portail ne l’est pas tellement. Et si je voulais créer une belle landing page ?

C’est pour ça que j’en arrive à la troisième et dernière solution : Créer votre propre portail d’authentification.

Comment créer votre portail d'authentification avec Shiny

Afin d’implémenter cette dernière solution, je vous propose un package appelé shinymanager.

Disponible sur le CRAN, vous pouvez l’installer (en local et sur votre serveur) facilement :

install.packages("shinymanager")

La page Github explique sommairement comment l’utiliser, la documentation reste encore très limitée : https://github.com/datastorm-open/shinymanager.

En descendant un peu sur la page, vous trouverez un exemple minimaliste pour ajouter le portail d’authentification.

Et ça marche :

Shiny AWS create application

Essayons de l’adapter à notre application sur l’explorateur de films (pour rappel, le code est disponible ici).

En lisant la page Github, on comprend qu’il faut faire les étapes suivantes :

  • Créer des identifiants,
  • Charger le package shinymanager,
  • Utiliser la fonction secure_app autour de l’UI,
  • Rajouter le module d’authentification dans la partie server.

C’est parti !

Créer des identifiants

C’est la partie la plus facile.

Je vais utiliser le même bout de code qu’eux pour rester simple pour le moment et je le mets dans le global.R :

credentials <- data.frame(
  user = c("shiny", "shinymanager"),
  password = c("azerty", "12345"),
  stringsAsFactors = FALSE
)

Alors oui, les identifiants sont écrits comme ça, en clair, pas chiffrés ni rien.

Vous vous doutez bien que ce n’est ni pratique ni sécurisé.

On verra un peu plus tard comment changer ça.

Charger le package shinymanager

Je le charge au début du fichier global.R, afin que les fonctions soient accessibles dans la partie serveur et dans la partie UI :

library(shinymanager)

Ajouter la fonction secure_app

Dans l’exemple de Github, l’appli minimaliste tient en un seul fichier.

Nous, on en a trois : global.R, server.R, et ui.R.

Les deux méthodes fonctionnent pour créer des applis Shiny.

Pas de souci ici.

Dans le fichier ui.R, repérez la partie UI. C’est le bout de code qui commence par fluidPage(, à la ligne 11.

Je rajoute la fonction secure_app :

secure_app(fluidPage(
  # Code à l'intérieur...
))

Et je n’oublie pas de refermer la parenthèse à la fin du fichier.

Ajouter le module d’authentification

Enfin, je vais juste copier/coller un bout de code au début de la fonction server, autour de la ligne 23 du fichier server.R :

# call the server part
# check_credentials returns a function to authenticate users
res_auth <- secure_server(
  check_credentials = check_credentials(credentials)
)

Et voilà !

Alors si on s’arrête là… ça ne va pas marcher.

En fait, l’appli va bugger à cause de ggvis.

Pour résoudre le problème, je lui dis juste de faire un graphe vide tant qu’on ne s’est pas connecté.

Je rajoute donc vis autour de la ligne 99, tout au début de la déclaration de la variable réactive :

vis <- reactive({
  if (is.null(input$xvar)) return(ggvis(data.frame(x = 0, y = 0), ~x, ~y))
  # Lables for axes
  # Reste du code...
})

Maintenant, c’est bon !

Vous pouvez voir le code mis à jour à l’adresse suivante : https://gitlab.charlesbordet.com/charles/movie-explorer-login.

J’ai hébergé l’application sur mon serveur Shiny.

Et voilà le résultat : https://shiny.charlesbordet.com/movie-explorer-login/.

Vous pouvez vous logger avec les identifants shiny/azerty par exemple.

Options supplémentaires

shinymanager ne s’arrête pas là heureusement.

Vous pouvez aussi :

  • avoir un mode admin pour gérer les utilisateurs,
  • utiliser une base de données chiffrée pour stocker les identifiants,
  • passer le portail en français.

Toutefois, tout n’est pas possible.

Par exemple, si vous voulez offrir une interface de création de compte pour vos utilisateurs… vous devrez le faire vous-même.

En fait, je trouve personnellement que shinymanager est un très bon point de départ.

Lorsque je crée des portails d’authentification pour mes clients, je suis les étapes suivantes :

  • Je vais chercher le code entier de shinymanager et l’ajoute à mon projet,
  • Je vire toutes les fonctionnalités dont je n’ai pas besoin (par exemple les logs ou l’interface d’admin),
  • Je rajoute les fonctionnalités dont j’ai besoin.

La première fois, ça m’a demandé de vraiment comprendre comment le package fonctionnait, notamment via l’utilisation de tokens d’authentification et une classe R6.

Mais c’était super intéressant et j’ai beaucoup appris !

Donc je recommande vraiment de passer du temps à comprendre ce package.

D’autant plus que comme la sécurité est un argument essentiel du portail d’authentification, le fait de comprendre les rouages de shinymanager vous permettra de comprendre aussi ses points forts et ses points faibles.

Par exemple le fait que le package ne hash pas les mots de passe avant de les stocker.. Pas bien !

Vous pouvez donc repartir de shinymanager et rajouter par exemple :

  • La possibilité de créer un compte,
  • L’utilisation de règles pour restreindre la création de compte (comme pour Auth0, mais vous l’écrivez en R cette fois-ci !),
  • Un service de “Mot de passe perdu”
  • Un système de cookies pour retenir la session de l’utilisateur
  • Le fait de hasher et saler les mots de passe
  • Et à peu près tout ce que vous voulez…

Au final, c’est une solution que j’aime beaucoup parce qu’elle est entièrement flexible.

Le seul point qui me dérange est la question de la sécurité.

Ce n’est pas mon expertise, je ne sais pas ce que je ne sais pas, et il faut se méfier très fortement de l’effet Dunning-Kruger (surestimer vos capacités en sécurité parce que vous avez lu 3 articles, en gros).

Donc si votre application brasse des données confidentielles, faites-vous accompagner par une personne compétente !

Comparatif final

Je vous ai récapitulé tous les avantages et inconvénients de chaque solution dans le tableau suivant :

Solution Prix Facilité de mise en œuvre Dépendance Sécurité Administration
Shiny Server Pro Cher Facile Indépendant Bonne Non
nginx Gratuit Facile Indépendant Bonne Non
Auth0 Gratuit jusqu’à 7000 utilisateurs Moyen Dépendant Bonne Oui
Solution maison Gratuit Difficile Indépendant Moyenne Oui

À présent, à vous de voir la solution la plus adaptée à votre situation !


Cet article conclut le dossier sur Comment déployer une application Shiny sur AWS.

J’espère que vous aurez trouvé cette série utile ! Merci à ceux qui m’ont fait des retours et qui m’ont permis d’améliorer les articles précédents.

Je sais qu’il y a encore plein d’autres sujets à traiter, comme le déploiement avec Docker, l’utilisation de shinyproxy.io, la scalabilité du déploiement, etc.

Ce sont des sujets que j’aborderai un peu plus tard, probablement dans un format différent.

Pour être tenu au courant de la publication des nouveaux articles, n’hésitez pas à vous inscrire ci-dessous !

Mis à jour :

Commentaires

Laisser un commentaire

Les champs obligatoires sont marqués *

Chargement...

Les commentaires sont validés manuellement. La page va se rafraîchir après envoi.