User authentication and password storage in R Shiny using sodium - r

I am implementing a log in page to a ShinyApp (I cannot use any paid features of Shiny Server Pro or anything like that) and came accross some sample code to do so on the following website:
https://www.listendata.com/2019/06/how-to-add-login-page-in-shiny-r.html
It uses the sodium package which is build on sodium to store and check passwords. The relevant code is
credentials = data.frame(
username_id = c("myuser", "myuser1"),
passod = sapply(c("mypass", "mypass1"), sodium::password_store),
permission = c("basic", "advanced"),
stringsAsFactors = FALSE,
)
The use inputs a username and password through a text box and then the shinyapp checks for a match using the function sodium::password_verify
The first thing I noticed is that the passwords get stored as rownames:
> credentials
username_id
mypass myuser
mypass1 myuser1
passod
mypass $7$C6..../....etc..
mypass1 $7$C6..../....etc..
permission
mypass basic
mypass1 advanced
Is this a mistake? Surely this defeats the point of storing the passwords as hashes.
Once I've added row.names = NULL to the dataframe, is this a reasonably secure method to store log in details? Are there other methods/packages or other free services to manage user accounts and authentication to Shiny?

Related

R JDBC snowflake connection using ssh key auth

I have a Rstudio setup with no browser and only terminal access to internet.
Having issues following the guides for snowflake connections with Rstudio and dplyr library using ssh keys for auth, can confirm access to the tenant via browser outside of terminal. I also tried the jdbcDriver jar directly and connection to no avail.
Any pointers would be helpful
Examples below, tried with and without region
install.packages(c("rJava"))
install.packages(c("RJDBC", "DBI", "dplyr"))
install.packages("devtools")
devtools::install_github("snowflakedb/dplyr-snowflakedb")
library(RJDBC)
library(dplyr)
library(dplyr.snowflakedb)
options(dplyr.jdbc.classpath = "/opt/snowflake-jdbc-3.9.2.jar")
snowflake_con <- src_snowflakedb(user = "myusername#domain.comm", password = "mypassword", private_key_file = "/home/ssh-keys/rsa_key.p8", private_key_file_pwd="myfilepassword", host = "myhost.eastus2.snowflakecomputing.com", opts = list(warehouse = "WAREHSE", db = "DB", schema = "CB", authenticator="externalbrowser"))
jdbcConnection <- dbConnect(jdbcDriver, "jdbc:snowflake://<account><.region_id>.snowflakecomputing.com", "<username>","<password>")
jdbcConnection <- dbConnect(jdbcDriver, "jdbc:myhost.eastus2.snowflakecomputing.com", private_key_file = "/home/ssh-keys/rsa_key.p8", private_key_file_pwd="myfilepassword")
tried following snowflakes guide here but this just uses username and password which requires the auth verified.
https://community.snowflake.com/s/article/connecting-r-to-snowflake-using-the-jdbc-driver-mac-os-x
https://snowflakecommunity.force.com/s/article/How-TO
You will either need a user configured with password authentication or Key Pair Authentication. SSO authentication will not work for you in the absence of a browser. After creating the keys, you will need to assign the key to the Snowflake user. Finally, here is how to configure JDBC configuration to use key pair authentication

Microsoft Graph API - error 403 "Insufficient privileges to complete the operation"

I'm trying to use the AzureR family of R packages to interact with Outlook through the Graph API. Using Microsoft365R I have the following code:
outl <- get_business_outlook(
tenant = tenant_id,
app = client_id,
password = client_secret
)
But this results in a 403 error:
Error in process_response(res, match.arg(http_status_handler), simplify) :
Forbidden (HTTP 403). Failed to complete operation. Message:
Insufficient privileges to complete the operation.
The app in question has the API permissions Mail.ReadWrite, Mail.ReadWriteShared, Mail.Send, Mail.Send.Shared, offline_access, openid, User.Read.
I also tried using the AzureGraph package directly like:
login <- create_graph_login(
tenant = tenant_id,
app = client_id,
password = client_secret
)
This works and I get a token. I then try to extract user information with me <- login$get_user(), but this throws the same 403 error as above. I suspect there is something I need to do to actually authenticate the user, but I can't really figure out what.
I am entirely new to the Graph API so it's very possible that I have missed something obvious. Any help appreciated!
Microsoft365R/AzureGraph author here. In the code you show, both with get_business_onedrive() and create_graph_login(), you are authenticating as the app, not as the user. This means that there is no user account involved, hence you're unable to view user details or send email.
To authenticate as the user, run
# Microsoft365R
get_business_outlook("tenant_id", app="client_id")
# AzureGraph
create_graph_login("tenant_id", app="client_id")
ie, without the password argument. You should know it's working if R opens up a browser window for you to login to Azure (or to show it's successfully logged in).
The latest revision of the AzureAuth package has a vignette that explains a bit more on the various authentication scenarios. AzureAuth::get_azure_token is the underlying function used to obtain an OAuth token by Microsoft365R and AzureGraph, and you can pass down the arguments mentioned in the vignette from get_business_outlook and create_graph_login.

Changing user password in PgAdmin on mac

I am using gAdmin on mac. So far I have not been able to figure out how to run the desktop version, so I am running the web application. I want to change the password for the user postres. The reason being, I am trying to connect R to postres using:
db <- 'dvdrental' #provide the name of your db
host_db <- "localhost"
db_port <- '5432'
db_user <- "postgres"
db_password <- " " # I typed the master password in, as I do not remember setting up this user/password
con<-dbConnect(RPostgres::Postgres(), dbname = db, host=host_db, port=db_port, user=db_user, password=db_password)
but I keep getting below error:
Error: FATAL: password authentication failed for user "postgres".
This is thee reason for the change of password for the user postgres
How can I change a user password in PgAmin4 using webapp on mac?
In PgAdmin4, if you are changing the password for the same user you are logged in as, then you need to select a connected database from the browser tree. Once you do that, the "Object" menu "Change Password..." option.
If you are logged into the server as a super user and want to change the password of a different user/role, then right click (or whatever mac uses for that function) on that user/role from the tree and choose "Properties...". Then under the "definition" tab there is a place to enter the new password. Note that this method is inferior, as the password is received by the server as plain text (once any ssl decryption is done) and so can end up in the log file in the clear.
Why constrain yourself to PgAdmin4? psql has \password, which does this better.

Glassfish Change Admin Password

How can I change the admin password for a Glassfish Domain using a password file? I know the conventional method of manually typing the password upon prompt.
However I want to change the admin password using a script where in I do not have to manually type the password.
This is possible, but you will need 2 password files if you want to script this fully in the easiest way.
Create a temporary file (tmpfile in my example) which will hold the current password (blank by default) and the desired new password:
AS_ADMIN_PASSWORD=
AS_ADMIN_NEWPASSWORD=myNewPassword
Now create a password (pwdfile in my example) file which will contain the changed admin password:
AS_ADMIN_PASSWORD=myNewPassword
You can then use the files to change the password using the commands below, making sure to use tmpfile when changing the password, then pwdfile afterwards
$PAYARA_PATH/bin/asadmin start-domain
$PAYARA_PATH/bin/asadmin --user $ADMIN_USER --passwordfile=/opt/tmpfile change-admin-password
$PAYARA_PATH/bin/asadmin --user $ADMIN_USER --passwordfile=/opt/pwdfile enable-secure-admin
$PAYARA_PATH/bin/asadmin restart-domain
This example was adapted from the way the Payara Server dockerfile works
For anyone still interested in manually setting the admin account password:
I tried to generate the contents of the "admin-keyfile" located in "glassfish/domains/{ACTIVE_DOMAIN_NAME}/config/admin-keyfile" based on the current implementation of the Payara Repo. This file (as the data source for the FileRealm) is used to authenticate the admin user when accessing the admin interface under port 4848.
Each line of this text file represents an account and is structured as
USERNAME;PASSWORD;GROUPS
The field "PASSWORD" is prefixed with a hash algorithm keyword (wrapped in curly braces, e.g. "SSHA" or "SSHA256") followed by a BASE64 encoded hash of the concatenated salted hash and the salt value itself (some random bytes):
{SSHA}BASE64(SHA(password,salt),salt)
Long story short: If you want to generate user accounts manually you could for example use the following Python script:
import hashlib
from base64 import b64encode
from secrets import token_bytes
from getpass import getpass
username = 'admin' # input('Username: ')
plainTextPassword = getpass()
randomSalt = token_bytes(8)
passwordHash = hashlib.sha256()
passwordHash.update(plainTextPassword.encode('utf-8'))
passwordHash.update(randomSalt)
passwordDigest = passwordHash.digest()
# cryptic range reflects the strange implementation... feel free to change it to "range(98)"
# https://github.com/payara/Payara/blob/6488cbdc90fd0f6c42de6a42affcd09f697be715/nucleus/common/common-util/src/main/java/org/glassfish/security/common/SSHA.java#L108
for run in range(2, 101):
passwordHash = hashlib.sha256()
passwordHash.update(passwordDigest)
passwordDigest = passwordHash.digest()
saltedHashAndSalt = b64encode(passwordDigest + randomSalt).decode('utf-8')
result = '{0};{{SSHA256}}{1};asadmin'.format(username, saltedHashAndSalt)
print(result)
Insert the console output into the "admin-keyfile" and (re)start your server.
As far as I know, it is impossible to change it via a file as a parameter for security reasons.
You can consider an alternative solution (pipe) but the confirmation of the password is always necessary. https://docs.oracle.com/cd/E19798-01/821-1758/change-admin-password-1/index.html

Non-interactive passwords in R

I'd like to revisit an old SO question about passwords. Like the OP, I don't want to enter my password interactively, but I am confused about how to store the password securely on my machine and share scripts with colleagues (and I'd add specifically, push scripts to GitHub). The accepted answer involves storing the password in .Rprofile, but one commenter suggests that this is not a good idea.
In my specific use case, I have a script that runs every day on a virtual machine that I want other members of my team to access. At the end of the run, it sends an email with the mailR package. This code looks for my gmail password. I've set up 2-step authentication, so mypassword is a third-party password, not my actual gmail password. Still, I am hesitant to share this with others. I'd like to be able to push the script to a private git repo.
send.mail(from = "myemail#gmail.com",
to = tolist,
subject = "my subject",
body = "my message",
smtp = list(host.name = "smtp.gmail.com", port = 465,
user.name = "myusername",
passwd = "mypassword",
ssl = TRUE),
authenticate = TRUE,
html = FALSE,
send = TRUE)
How would you store mypassword?
Storing it in .Rprofile seems to be an option, but I don't know if there are downsides like the one mentioned in response to the accepted answer in the question I linked to.
I could store it in another file like auth.R and run source('auth.R') before send.mail, but this would put the password in the global environment.
Other ideas?

Resources