I am trying to embed a ShinyProxy app in a web portal using an iframe. What I am trying to accomplish is for the Shiny app to be accessible to only users who are logged in to a web portal and for it to not be accessible to users who are not logged in.
I am trying to use the API similar to https://github.com/openanalytics/shinyproxy-config-examples/blob/master/07-api-embedded-app/index.html and it is not working properly. It displays an error “Not authorized to access this proxy”. I am trying to get this API working with authentication set to “none” for testing purposes but ultimately we probably will use ldap or openid.
I have set up ShinyProxy on a Ubuntu server and a docker image andrewpmk/provinces with a demo R shiny app (shows a graph of the population of provinces and territories in Canada) for testing purposes and I have set up a nginx reverse proxy and it is working when viewed outside an iframe.
Here is my application.yml:
proxy:
title: Open Analytics Shiny Proxy
landing-page: /
heartbeat-rate: 10000
heartbeat-timeout: 60000
port: 8080
authentication: none
docker:
cert-path: /home/none
url: http://localhost:2375
port-range-start: 20000
specs:
- id: provinces
display-name: Provinces
description: Provinces and Territories of Canada
container-cmd: [“R”, “-e”, “shiny::runApp(’/root/shinyapp’)”]
container-image: andrewpmk/provinces
logging:
file:
shinyproxy.log
I am using the following JavaScript. Note that I have obscured the name of my ShinyProxy server for privacy reasons.
var hostURL = “SERVER”;
var proxySpecId = “provinces”;
var currentProxy = null;
var launchProxy = function () {
console.log("Launching " + proxySpecId + “…”);
$.ajax({
type: “POST”,
url: hostURL + “/api/proxy/” + proxySpecId,
contentType: “application/json”,
data: “[]”,
success: function (data) {
currentProxy = data;
console.log(JSON.stringify(currentProxy));
showProxy();
}
});
};
var showProxy = function () {
if (currentProxy == null) {
console.log(“No active proxy!”);
return;
}
var endpointURL = hostURL + “/api/route/” + Object.keys(currentProxy.targets)[0] + “/”;
$("#proxyIFrame").attr(“src”, endpointURL);
}
$(function () {
launchProxy();
});
When launchProxy() is run it successfully communicates with the API and downloads a JSON payload (which I can verify using the JavaScript debugger). But showProxy doesn’t work - it is setting the src of the iframe #proxyIFrame on my page to SERVER/api/route/TOKEN/ where token is the value of Object.keys(currentProxy.targets)[0] obtained from the JSON payload from launchProxy(). When I set the iframe’s src it displays an error “Not authorized to access this proxy”. What am I doing wrong?
I have changed /etc/nginx/nginx.config to allow cross-origin requests by adding the following:
add_header Access-Control-Allow-Origin *;
if ($request_method = OPTIONS ) {
add_header Access-Control-Allow-Origin *;
add_header “Access-Control-Allow-Methods” “GET, POST, OPTIONS, HEAD”;
add_header “Access-Control-Allow-Headers” “Authorization, Origin, X-Requested-With, Content-Type, Accept”;
return 200;
}
so blocking cross-origin requests is not the cause of the problem.