10

I have two applications.

  1. R Shiny app hosted on EC2
  2. Asp.net application hosted on Azure.

The asp.net app preforms user authentication and is used to organize a whole data science pipeline. A user provides data, the data scientist transforms the data and delivers a shiny app. Finally, the user opens the Shiny app within the asp.net application.

The problem I have is that I don't know how to integrate the Shiny app that I have developed within the asp.net application securely.

I could solve the problem like this:

enter image description here

Basically, I can make a simple iframe with a link to the public domain of the EC2 instance. However, this is not secure. Anybody can find and access the url with a simple page source click.

Another option that I have considered is to limit the IP address in the EC2 security groups. However, the problem is that the asp.net application is supposed to be used by different entities/independent users. So the security needs to be more granular [does the user have access to app, project within app, container within a project?] than just a server IP address.

Also, I have thought to provide a second level of authentication within the actual Shiny app, however this essentially loses the point of the asp.net authentication in the first place.

Any ideas or hints in what direction I should continue with research?

Prometheus
  • 1,977
  • 3
  • 30
  • 57
  • Have a look at https://www.shinyproxy.io/, theres no really a way to hide the URL source from others. Because then you simply wont know who is the owner of the content – Pork Chop Jul 12 '18 at 16:35

2 Answers2

2

I think you're right, there are two options. The first is to create a secure connection between the two servers and use the .Net app to proxy the traffic, but that defeats the point.

The second is to authenticate the use with both servers. You could do this by having the .Net server somehow pass data about the active sessions to the Shiny app to synchronise them but that isn't ideal.

You could instead use an authentication mechanism such as JWT where the .Net server would issue the client a token (i.e. cookie or embedded into the iFrame URL) when they log in and the client would then pass this to the token to the Shiny server, which would only have to validate the token. If using cookies you would need to make sure both servers are on the same subdomain so that the token is set properly.

OllyTheNinja
  • 566
  • 3
  • 16
0

Disclaimer:

Mine is a bit similar to what @OllyTheNinja has explained. Since I am not familiar with JWT, I cannot compare these two approaches but would love to hear more possible integration approaches.

I can think of another way and this is generating a random number (about 20 characters) in the ASP.Net for a user at the login page and record the time and token in a shared medium (e.g. database). Then when a user clicks on the button which takes them to the shiny URL, attach that token to the URL and pass it to the Shiny server, then parse the URL and find the token and search it in the database (you can define an expiry date since you are recoding the generation time). If exists, load the page, otherwise redirect to another page.

For parsing this may help: https://shiny.rstudio.com/reference/shiny/1.6.0/parseQueryString.html

For attaching the token to the URL, I think you can use Ajax, I have not written any .Net code for a long time, but I am sure there is a way, maybe something like this: How can I use $.ajax to set image src to dynamic image/png data?

I guess it would be nice to log the client properties (e.g. IP) at Shiny and put a logic that if requests are coming from the same IP, browser, then do not check the validity of the token until a few hours. In this way, you are kind of building your own firewall as well.

Since the token is long enough (i.e. ~20 characters), there are 20^(~72, i.e. 26 letters lowercase+26 letters uppercase+ ~ 10 special characters+ 9 digits) possible permutations which almost make it impossible to crack, especially if you define an expiry date of about 1-2 hrs per token.

Mohsen Sichani
  • 1,002
  • 12
  • 33