Acquiring different token for multiple users in Shiny
Closed this issue · 10 comments
I have a Shiny app which runs in the network and multiple users can access it.
With the help of the instructions, Azure authentication work without any issue.
In order to extract user information, I call another tokenuser <- get_azure_token
but it returns same user's information in the app.
library(AzureGraph)
library(AzureAuth)
library(AzureRMR)
library(shiny)
myresource <- 'xxxx'
mytenant <- 'xxxx'
myapp <- 'xxx'
myredirect='http://localhost:2121'
mysecret <- 'xxxx'
ui = function(req) {
qs <- parseQueryString(req$QUERY_STRING)
redirect <- NULL
if (is.null(qs$code)) {
auth_uri <- build_authorization_uri(myresource, mytenant, myapp, redirect_uri=myredirect, version=2)
redirect <- tags$script(HTML(paste0('window.location.replace(\'', auth_uri, '\');')))
}
fluidPage(
tags$head(
redirect
),
titlePanel('Old Faithful Geyser Data'),
actionButton('go', 'Go'),
sidebarLayout(
sidebarPanel(
sliderInput('bins','Number of bins:',min = 1,max = 50,value = 30)),
mainPanel(plotOutput('distPlot'))
)
)}
server <- function(input, output,session) {
qs <- isolate(parseQueryString(session$clientData$url_search))
if (!is.null(qs$code)) {
code <- qs$code
token <- get_azure_token(resource = c('https://graph.microsoft.com/.default', 'openid', 'profile', 'email'),
mytenant, myapp, password=mysecret,
authorize_args=list(redirect_uri=myredirect),
auth_code=code, version=2, use_cache=FALSE)
tokenuser <- get_azure_token(resource='https://graph.microsoft.com/.default',
app=AzureRMR:::.az_cli_app_id,version=2, use_cache = FALSE)
tokenuserinfo<-decode_jwt(tokenuser)$payload
}
output$userinfo<-renderText(paste(tokenuserinfo$given_name,tokenuserinfo$family_name,tokenuserinfo$email))
output$distPlot <- renderPlot({
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = 'darkgray', border = 'white')
})
}
shinyApp(ui = ui, server = server)
Many thanks in advance
Try adding the prompt="login"
option on the call to get the authorization code: build_authorization_uri(*, prompt="login")
. This will force AAD to ask for the user's credentials.
Thank you.
I have added it. Still the issue is same; logged in with user1 and it shows user1's name, logged in with user2 in another machine but it still shows user1's name.
When I execute below line from R it says "Using client_credentials flow", is it normal as I was expecting it to use authorization code?
I was assuming I could get any info about user with the single token only by adding "email" is in the scope or "User.Read" .
mytoken <- get_azure_token(resource = c("https://graph.microsoft.com/.default", "openid", "profile", "email","offline_access")
,tenant= mytenant
,app= myapp
,password=mysecret,
authorize_args=list(redirect_uri=myredirect),
auth_code=code, version=2, use_cache=FALSE)
Using client_credentials flow
If you include the password arg, that will cause get_azure_token
to default to client credentials, in which case the password is used as the client secret. I have no idea what the email
scope will do in this case, as you don't have a logged-in user.
Still the issue is same; logged in with user1 and it shows user1's name, logged in with user2 in another machine but it still shows user1's name.
Please provide more details on how exactly you "log in with user1" and also with "user2 on another machine". Do you mean that your machine running the Shiny server has 2 separate client sessions on different machines? Or what?
I do not have Shiny server but I have above Shiny app running in a machine in the internal network.
I would like the other users to be able to login to this Shiny app from other machines in same network using this library.
That login part runs perfectly without any issue, i.e other users from other machines can login with their credentials.
However I was not able to grab any information about the user (email or name).
I have checked #17 .
token<-...
in my code works without any error and gets users in.
In order to retrieve I inserted below part from my above code. It returns first user's information.
I might be in wrong path.
tokenuser <- get_azure_token(resource='https://graph.microsoft.com/.default',
app=AzureRMR:::.az_cli_app_id,version=2, use_cache = FALSE)
Add auth_type="authorization_code"
in the get_azure_token
call. Remove the password arg.
With the
token <- get_azure_token(resource = c("https://graph.microsoft.com/.default", "openid", "profile", "email","offline_access")
,tenant= mytenant
,app= myapp,
auth_type="authorization_code",
authorize_args=list(redirect_uri=myredirect),
auth_code=code, version=2, use_cache=FALSE)
It returns
Warning: Error in as.character: cannot coerce type 'closure' to vector of type 'character'
61: curl::curl_escape
60: FUN
59: vapply
58: compose_query
56: body_config
54: httr::POST
53: private$initfunc
52: <Anonymous>
50: initialize
49: AzureTokenAuthCode$new
48: get_azure_token
47: server [C:\ESG\ESG_Form/app.R#452]
Error in as.character(url) :
cannot coerce type 'closure' to vector of type 'character'
Change your redirect to a mobile & desktop redirect.
Now the situation changed to below;
If I would try to login from the server, it opens another Azure login page in the server and then let's me in.
If I would try to login from another machine (client), it opens the Azure login page in the server, but the user would not be able to see it from client machine.
I think at this point there's nothing wrong with the package. Consider asking on Stackoverflow or the RStudio community forums for tech support.