Greetings - I am trying to get an interactive application working for the lates Rocker rstudio singularity container. The container starts cleanly but when I click the ‘Connect to Rstudio’ button, it launches a new tab with a sign on error. Checking output.log, I see an error like this:
2022-01-11T21:52:16.353468Z [rserver] ERROR Failed to validate sign-in with invalid CSRF form; LOGGED FROM: bool rstudio::server::auth::common::validateSignIn(const rstudio::core::http::Request&, rstudio::core::http::Response*) src/cpp/server/auth/ServerAuthCommon.cpp:132
Taking a look with the Firefox inspector at the connect button, I see that the token seems to be getting passed:
<input id="csrfToken" type="hidden" name="csrf-token" value="1b6b3890-e329-4eb6-8ea2-c096a65bcf64">
Here are (what I think are) the key files.
submit.yml.erb :
---
batch_connect:
template: "basic"
conn_params:
- csrf_token
view.html.erb:
<script>
var hostButton=$( "a.btn.btn-primary.btn-sm.fas.fa-terminal" );
var hostname=hostButton.text();
hostButton.replaceWith(hostname);
document.cookie = "csrf-token=<%= csrf_token %>; path=/rnode/<%= host %>/<%= port %>; secure";`
</script>
<form action="/rnode/<%= host %>/<%= port %>/auth-do-sign-in" method="post" target="_blank">
<input type="hidden" name="username" value="<%= ENV["USER"] %>"/>
<input type="hidden" name="password" value="<%= password %>"/>
<input type="hidden" name="staySignedIn" value="1"/>
<input type="hidden" name="appUri" value=""/>
<input id="csrfToken" type="hidden" name="csrf-token" value="<%= csrf_token %>"/>
<button class="btn btn-primary" type="submit">
<i class="fab fa-r-project"></i> Connect to RStudio Server
</button>
</form>
before.sh.erb:
# Export the module function if it exists
[[ $(type -t module) == "function" ]] && export -f module
# Find available port to run server on
port=$(find_port ${host})
# Define a password and export it for RStudio authentication
password="$(create_passwd 16)"
export RSTUDIO_PASSWORD="${password}"
# For v1.4
<%-
require 'securerandom'
csrftoken=SecureRandom.uuid
-%>
export csrf_token="<%= csrftoken %>"
script.sh.erb:
#!/usr/bin/env bash
# Load the required environment
setup_env () {
# Additional environment which could be moved into a module
# Change these to suit
workdir="$HOME/rstudio-server"
export RSTUDIO_SERVER_IMAGE="$HOME/singularity-images/rstudio-server.sif"
export SINGULARITY_BINDPATH="$workdir/run:/run,$workdir/var/lib/rstudio-server:/var/lib/rstudio-server,$workdir/database.conf:/etc/rstudio/database.conf,$workdir/home:/home/rstudio,/sys/fs/cgroup"
# export PATH="$PATH:/usr/lib/rstudio-server/bin"
# export SINGULARITYENV_PATH="$PATH"
# In Singularity 3.5.x it became necessary to explicitly pass LD_LIBRARY_PATH
# to the singularity process
export SINGULARITYENV_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
}
setup_env
#
# Set up bind directories
#
mkdir -p -m 700 ${workdir}/run ${workdir}/var/lib/rstudio-server ${workdir}/home
cat > ${workdir}/database.conf <<END
provider=sqlite
directory=/var/lib/rstudio-server
END
#
# Start RStudio Server
#
# PAM auth helper used by RStudio
export RSTUDIO_AUTH="${PWD}/bin/auth"
# Let's use a consistent personal library location
export R_LIBS_USER=${workdir}/home/R/rocker-rstudio/4.1 # image specific
# Generate an `rsession` wrapper script
export RSESSION_WRAPPER_FILE="${PWD}/rsession.sh"
(
umask 077
sed 's/^ \{2\}//' > "${RSESSION_WRAPPER_FILE}" << EOL
#!/usr/bin/env bash
export OMP_NUM_THREADS=${SLURM_JOB_CPUS_PER_NODE} # SLURM specific
# Launch the original command
echo "Launching rsession..."
exec rsession "\${@}"
EOL
)
chmod 700 "${RSESSION_WRAPPER_FILE}"
# Set working directory to home directory
cd "${HOME}"
export myTMPDIR="$TMPDIR"
mkdir -p "$myTMPDIR/rstudio-server"
# Make myTMPDIR writeable
chmod -R 777 $myTMPDIR
chmod -R 777 $TMPDIR
python -c 'from uuid import uuid4; print(uuid4())' > "$myTMPDIR/rstudio-server/secure-cookie-key"
chmod 0600 "$myTMPDIR/rstudio-server/secure-cookie-key"
export SECURE_COOKIE_KEY="${myTMPDIR}/rstudio-server/secure-cookie-key"
set -x
# Launch the RStudio Server
echo "Starting up rserver..."
singularity run -B "$myTMPDIR:/tmp,$myTMPDIR" "$RSTUDIO_SERVER_IMAGE" \
rserver --www-port "${port}" \
--auth-none 0 \
--auth-pam-helper-path "${RSTUDIO_AUTH}" \
--auth-minimum-user-id=500 \
--auth-encrypt-password 0 \
--rsession-path "${RSESSION_WRAPPER_FILE}" \
--secure-cookie-key-file "${SECURE_COOKIE_KEY}" \
--server-user $USER
echo 'Singularity as exited...'
And finally, connection.yml, for this example, looked like this:
csrf_token: 1b6b3890-e329-4eb6-8ea2-c096a65bcf64
host: c4-n12
port: 9051
password: 6wde4T0irIaOKy92
So, I am struggling to understand how this token is supposed to be used and why rstudio server considers this one an invalid CSRF form. Any pointers would be greatly appreciated.