Shiny Server authentication?

3,910 views
Skip to first unread message

Adam Edgley

unread,
Jan 16, 2013, 8:18:19 AM1/16/13
to shiny-...@googlegroups.com
Hi,
I was wondering if there were plans to include some sort of authentication mechanism in Shiny Server. I think it has definite potential, but authentication (preferably via LDAP/ActiveDirectory) would be a necessity for me.

Thanks,
Adam

Joe Cheng

unread,
Jan 16, 2013, 12:30:34 PM1/16/13
to shiny-...@googlegroups.com
This is planned for the "enterprise edition" of Shiny Server.



--
 
 

Jacques Philip

unread,
Jan 18, 2013, 3:51:43 PM1/18/13
to shiny-...@googlegroups.com
Hello,

I was able to add basic or digest authentication (only to the HTTP server) by just adding a reference to the http-auth node.js module as well as a few extra lines of code in the file http.js of the lib/proxy directory of the shiny-server package. (That goes for the power of node.js)
I hard coded the user names and hashes in the file for now, but it seems it would be easy to have options in the config file for auth [None, Basic, Digest] and path to a paswd file.

It does not seem to disrupt the application, but I did not do much testing. Also, I am not knowledgeable enough to know if authenticating the HTTP server is enough or if the potential websockets connection is a security hole.

Would it be possible to add this type of basic/diggest auth to the open source version and leave LDAP and the likes for the enterprise version?

Just a thought.

Jacques

--
 
 

floe

unread,
Feb 19, 2013, 2:01:24 PM2/19/13
to shiny-...@googlegroups.com
Hi,

I have also tried to provide a (simple) authentication to shiny-server applications. Therefore I installed the node.js module "http-auth" using npm (no, it did not work at the first attempt):
npm install http-auth

As jphilip, I also manipulated "/usr/lib/node_modules/shiny-server/lib/proxy/http.js".
After the the first block of code where all the libraries are loaded I added:
var auth = require('http-auth');
var basic = auth({  
    authRealm : "Private area.",   
    authList : ['user1:pwd1', 'user2:pwd2']                                                                                                                                                                                                                                                 
});  

The authentication logic is applied directly to the httpListener. Therefore after
this.httpListener = function(req, res) {
the following line is inserted:
basic.apply(req, res, function(username) {});

After saving and closing the file, the server has to be restarted.
Now when loading any site provided by shiny-server, username and password have to be entered.
Be aware that this is a very inflexible and unsafe hack.

I would be most interesting how the entered username can be passed to the corresponding R instance(s)?!

Hopefully a more intelligent authentication feature will be added to future versions :)


FloE

floe

unread,
Feb 20, 2013, 8:29:11 AM2/20/13
to shiny-...@googlegroups.com
The entered username can be passed to the corresponding R instance by utilizing the AppSpec Object (appSpec instance) located in lib/worker/app-spec.js .
Inside the httpListener in lib/proxy/http.js (--> last post!) the following authentication code is inserted:

basic.apply(req, res, function(username) { 
  router.getAppSpec_p(req, res)
  .then(function(appSpec) {
    appSpec.settings.loginName = username;
  })
});

This property of appSpec has to be passed to a newly spawned R process by altering lib/worker/app-worker.js around line 150. At the end of the parameter to "this.$proc.stdin.end", where the stdin ('command line') parameters of the R process are generated, the following line is added:
(appSpec.settings.loginName || '') + '\n'
(Do not forget the additional "+" in the line above.)

Next the new command line parameter has to be added to the R environment. In "./R/SockJSAdapter.R" these parameters are read right at the beginning and are copied to the local R environment. Therefor the "Sys.setenv" function gets a new entry:
USERNAME=input[4]
(Again do not forget to get the "," etc. right.)

Finally the provided username can be used inside the shiny (R) application:
Sys.getenv('USERNAME')

 Yet again be aware that this is a crude hack by a highly inexperienced user (in fact I've seen any details about node.js for the first time about 24 ago :)

FloE

Adam Edgley

unread,
Feb 21, 2013, 4:49:35 AM2/21/13
to shiny-...@googlegroups.com
Simple authentication isn't an issue for me - they have to be authenticated in the local network to see the server anyway. I think the devs are looking to implement group-based LDAP authentication to allow for finer grained control over the various shiny applications.


--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Adam Edgley
0412 793 367
adam....@gmail.com

Paul Rigor

unread,
Jun 14, 2013, 9:20:34 PM6/14/13
to shiny-...@googlegroups.com
Have there been further discussions for supporting LDAP-based authentication? Will this be part of the "community" or only "enterprise" version? Thanks,
Paul

Joe Cheng

unread,
Jun 17, 2013, 6:59:28 PM6/17/13
to shiny-...@googlegroups.com
Hi Paul, it is coming as part of the "enterprise" version. It will probably not be in the initial beta that we're currently working on, but should be part of the v1. (Sorry, no dates at this time.)

ste...@inizio.se

unread,
Jun 18, 2013, 3:54:01 AM6/18/13
to shiny-...@googlegroups.com
I know this is an old thread... 

I'm trying to use basic authentication described by FloE, but something goes wrong. I used the -g option to "npm install", but apart from that, i copied and pasted the code as-is.

This is what I use:

R version: 3.0.1
shiny: 0.6.0
node: v0.8.22
npm: 1.2.14
Debian GNU/Linux: 2.6.32-5-amd64

This is the info i get from shiny-server:

[2013-06-18 09:06:22.081] [INFO] shiny-server - Shiny Server v0.3.5 (Node.js v0.8.22)
[2013-06-18 09:06:22.082] [INFO] shiny-server - Using config file "/usr/local/lib/node_modules/shiny-server/config/default.config"
[2013-06-18 09:06:22.096] [INFO] shiny-server - Starting listener on 0.0.0.0:3838
[2013-06-18 09:06:26.792] [ERROR] shiny-server - Uncaught exception: Error: Can't render headers after they are sent to the client.

/usr/local/lib/node_modules/shiny-server/lib/main.js:202
  throw err;
        ^
Error: Can't render headers after they are sent to the client.
    at ServerResponse.OutgoingMessage._renderHeaders (http.js:715:11)
    at ServerResponse.res._renderHeaders (/usr/local/lib/node_modules/shiny-server/node_modules/connect/lib/patch.js:69:27)
    at ServerResponse.writeHead (http.js:1059:20)
    at ServerResponse.res.writeHead (/usr/local/lib/node_modules/shiny-server/node_modules/connect/lib/patch.js:75:22)
    at Object.sendPage (/usr/local/lib/node_modules/shiny-server/lib/core/render.js:34:12)
    at $autoindex_p (/usr/local/lib/node_modules/shiny-server/lib/router/directory-router.js:201:14)
From previous event:
    at DirectoryRouter.getAppSpec_p (/usr/local/lib/node_modules/shiny-server/lib/router/directory-router.js:72:6)
    at /usr/local/lib/node_modules/shiny-server/lib/router/router.js:116:21
    at tryNext (/usr/local/lib/node_modules/shiny-server/lib/core/qutil.js:90:9)
    at Object.forEachPromise_p (/usr/local/lib/node_modules/shiny-server/lib/core/qutil.js:110:3)
    at Object.getFirstAppSpec_p (/usr/local/lib/node_modules/shiny-server/lib/router/router.js:113:16)
    at ServerRouter.getAppSpec_p (/usr/local/lib/node_modules/shiny-server/lib/router/config-router.js:207:19)
    at /usr/local/lib/node_modules/shiny-server/lib/router/router.js:116:21
    at tryNext (/usr/local/lib/node_modules/shiny-server/lib/core/qutil.js:90:9)

I'm so close... I think!

floe

unread,
Jun 18, 2013, 11:47:04 AM6/18/13
to shiny-...@googlegroups.com
Hi,

I updated my installation (hosted at Amazon EC2) recently to:
R 3.0.1
npm 1.2.25
nodejs 0.10.10
Ubuntu 12.04.2 LTS
shiny 0.6.0 (with some additional rude patches :)
(... newest available versions everywhere ...)

In the shiny-server logs the same error messages appear occasionally when a new session is initialized. Unfortunately I do not really understand why and where these errors are generated or how to get rid of them.

As the shiny application including password authentication nevertheless works as expected and the whole project is a quite early beta, I currently don't really care about these error messages and am waiting for the next release. If authentication mechanisms are not implemented by then we still could spend more time refining these codes.

FYI: I'm currently trying to proxy the shiny-application using nginx for load balancing, QOS and above all SSL encryption. If this works an encrypted and password protected application based on shiny would be possible!

--
all the best
FloE

ste...@inizio.se

unread,
Jun 18, 2013, 3:59:46 PM6/18/13
to shiny-...@googlegroups.com
S: Hmm... So Your application actually survives the error and resumes, without the user knowing about the error? In my case, I start shiny-server from the command line, and when I point my browser to the application, shiny-server dies and does not recover. My browser fills with "page can not be displayed" (or something similar).

Am I starting shiny-server incorrectly?

floe

unread,
Jun 19, 2013, 5:19:35 AM6/19/13
to shiny-...@googlegroups.com


On Tuesday, June 18, 2013 9:59:46 PM UTC+2, ste...@inizio.se wrote:
S: Hmm... So Your application actually survives the error and resumes, without the user knowing about the error?

right
 
In my case, I start shiny-server from the command line, and when I point my browser to the application, shiny-server dies and does not recover. My browser fills with "page can not be displayed" (or something similar).

I suggest to check if the shiny-server is really responsible for this problem by loading one of the included and documented examples. I saw different strange error messages in my adapted as well es in vanilla installations which were caused by my own R code.
 
Am I starting shiny-server incorrectly?

In Ubuntu (and Debian) the server is started/stopped/... using
start shiny-server
stop shiny-server
restart shiny-server


 

ste...@inizio.se

unread,
Jun 19, 2013, 11:13:27 AM6/19/13
to shiny-...@googlegroups.com
S: My Debian installation does not accept 'start shiny-server'. I get '-bash: start: command not found' when I try it. The only way I can start it is with a simple 'shiny-server' from the command line.

You are probably right about the cause of the error. I think originates from the authentication i add to '/usr/lib/node_modules/shiny-server/lib/proxy/http.js'. When I comment out the lines I add from the suggestion above, the examples shipped with shiny-server works fine. When I activate the authentication, the server crashes as described. 

When I load one of the example apps, I get the authentication dialog, prompting for a username and a password. But shiny server has already crashed...

floe

unread,
Jun 20, 2013, 1:15:33 AM6/20/13
to shiny-...@googlegroups.com
There are different service-managment approaches available in Debian and Ubuntu Server (which I'm using). Generally I don't think that the way you start the service/server is really important for this problem.

Perhaps it was just good luck when I 'hacked' this functionality into shiny server. Most technologies used in this context are still rather new to me...
Please post here if you find the reason for your problems or a solution :)

Sam

unread,
Jul 10, 2013, 8:17:14 AM7/10/13
to shiny-...@googlegroups.com
Hi
i am very interesting by this feature and I modified the files as you suggest. Unfortunately, nothing changes : the command Sys.getenv('USERNAME') in RStudio Server gets an empty string

Any idea to help me ?

thanks

Sam

floe

unread,
Jul 11, 2013, 1:57:45 PM7/11/13
to shiny-...@googlegroups.com
Hi,

I think it is not possible to test this feature in RStudio Server as the environment variable 'USERNAME' is passed by the shiny server (node.js) to the corresponding R process. You won't get this information in another R process.

Perhaps it helps if you print the whole
Sys.getenv()
output in a text field of your shiny application (after logging in etc.)

--
Florian

Sam

unread,
Jul 12, 2013, 7:56:50 AM7/12/13
to shiny-...@googlegroups.com
HI Floe

this time, it is near working. I have the login window which asks for a username and password but, even if I write nothing, the shiny-server shutdowns with this message : shiny-server
[2013-07-12 13:54:26.806] [INFO] shiny-server - Shiny Server v0.3.6 (Node.js v0.10.12)
[2013-07-12 13:54:26.811] [INFO] shiny-server - Using config file "/usr/local/lib/node_modules/shiny-server/config/default.config"
[2013-07-12 13:54:26.889] [INFO] shiny-server - Starting listener on 0.0.0.0:3838
[2013-07-12 13:54:35.486] [ERROR] shiny-server - Uncaught exception: Error: Can't set headers after they are sent.

/usr/local/lib/node_modules/shiny-server/lib/main.js:202
  throw err;
        ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:704:11)
    at ServerResponse.res.setHeader (/usr/local/lib/node_modules/shiny-server/node_modules/connect/lib/patch.js:59:22)
    at SendStream.setHeader (/usr/local/lib/node_modules/shiny-server/node_modules/send/lib/send.js:473:44)
    at SendStream.send (/usr/local/lib/node_modules/shiny-server/node_modules/send/lib/send.js:349:8)
    at /usr/local/lib/node_modules/shiny-server/node_modules/send/lib/send.js:327:10
    at Object.oncomplete (fs.js:107:15)

Do you have an idea of what is going wrong ?

Sam

floe

unread,
Jul 12, 2013, 11:01:28 AM7/12/13
to shiny-...@googlegroups.com
Hi Sam,

It seems like others who have tried this hack ran into the same problems.
I also see these error messages in the log when the user logs in. Nevertheless my Shiny / R application works as expected.

Most likely the http-auth handler is inserted at the wrong position and called too late in the whole process of establishing a valid http connection.
Perhaps the whole httpListener function has to be adapted or the authentication has to take place even earlier.

--
all the best
Florian

Mike C

unread,
Jul 12, 2013, 11:06:57 AM7/12/13
to shiny-...@googlegroups.com
I was wondering, if the app is hosting on a groups own server, and not glimmer/spark/etc, is it easier to put a log in/authenticator to allow the page to load, or does it run into the same problems?

Florian Endel

unread,
Jul 12, 2013, 11:11:11 AM7/12/13
to shiny-...@googlegroups.com
I'm hosting these apps on a costum installation in the Amazon cloud.
The system is based on Amazons Ubuntu Server edition and the installation provided on the Shiny git-page.

I have no experiences with glimmer or other providers...


--
You received this message because you are subscribed to a topic in the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/shiny-discuss/3HbwHXBTzNo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to shiny-discus...@googlegroups.com.

Mike C

unread,
Jul 12, 2013, 12:13:04 PM7/12/13
to shiny-...@googlegroups.com
Cool, and you have no problem setting up a login/authentication system there?
Message has been deleted

floe

unread,
Jul 15, 2013, 10:47:30 PM7/15/13
to shiny-...@googlegroups.com
No - not really.
You may try it on your own. Just register for Amazon EC2 and get a micro instance for free (for 1 year).

Login to EC2 and follow this link:
https://console.aws.amazon.com/ec2/home?region=eu-west-1#launchAmi=ami-a77768d3
  • An new instance is created:
  • Continue with the first screen
  • Select t1.micro (the standard) or a stronger but more expensive 'hardware' and continue
  • Kernel ID: aki-71665e05 (this is important for XEN because I updated the kernel) and continue
  • Continue till the Key-Creation --> you will need the created .pem file to login using SSH
  • Security: you will need TCP Port 22 (SSH), 3838 (Shiny) and 8787 (RStudio)
  • Launch :)
After the instance started you have to start shiny. Connect with SSH and type
sudo start shiny-server

Now you can to visit the website
<your-instance-public-dns>:3838

user: test
pass: test

(can be changed at runtime in /usr/lib/node_modules/shiny-server/lib/proxy/users.htpasswd using the tool htpasswd)

You will find all standard shiny examples working including the described login-hack. In most of them the username from login is displayed in the sites header. The server includes
R 3 with openblas
RStudio
shiny
some other nice packages

ToDos:
HTTPS proxy for RStudio and Shiny using nginx (a necessary patch is already included).

--
all the best
FloE

Devopsman

unread,
Aug 9, 2013, 2:53:36 PM8/9/13
to shiny-...@googlegroups.com
I don't have this line in my http.js

this.httpListener = function(req, res) {
so I don't know where to  put the line below
basic.apply(req, res, function(username) {});


Do you have a sample?
Reply all
Reply to author
Forward
0 new messages