Closed LeoTimmermans closed 3 years ago
Yes, you can do this, although it's not very well documented.
AzureGraph::create_graph_login()
get_sharepoint_site
methodPut something like this in your server.R (or maybe ui.R, I'm not that familiar with how Shiny works):
token <- AzureAuth::get_azure_token(...) # your existing code here
# must load Microsoft365R to ensure class methods are updated
library("Microsoft365R")
gr <- AzureGraph::create_azure_login(token=token)
site <- gr$get_sharepoint_site("site name")
Thanks for the response. I think I am getting closer but not there yet.
create_azure_login gives an error:
AzureGraph::create_azure_login(token=token) Error: 'create_azure_login' is not an exported object from 'namespace:AzureGraph'
I guess it needs to be:
gr <- AzureGraph::create_graph_login(token=token)
When I use this I get following error:
AzureR data directory does not exist; login credentials not saved. Warning: Error in process_response: Forbidden (HTTP 403). Failed to complete operation. Message: Forbidden (HTTP 403). Failed to complete operation. Message: Access denied.
shinyapps.io does not have persistant data storage. Also the folder structure is different from a windows machine. So a folder for caching a token does not exist for shiny apps hosted on shinyapps.io (or in another instance of shiny server).
The root for shiny apps on shinyapps.io is: /srv/connect/apps/
The error message occurs at the step:
site <- gr$get_sharepoint_site("site name")
.
This still gives me following info:
However the shiny app fails when I try to get data or info from the sharepoint site. For instance:
drives <- site$list_drives(), items <- site$list_items() or drive <- sp_site$get_drive()
This means I still do not have access to the data on the sharepoint site.
Ok, in that case, try
library("Microsoft365R")
gr <- AzureGraph::ms_graph$new(token=token)
site <- gr$get_sharepoint_site("site name")
I'll look into fixing AzureGraph and AzureRMR to not assume the presence of a caching directory.
However the shiny app fails when I try to get data or info from the sharepoint site.
If you managed to obtain the site object, that means Microsoft365R is working. If you can't list the drives, there must be an issue with the permissions you've set on your app registration. Are you using the app reg from Microsoft365R, or something else?
Actually, AzureGraph/Microsoft365R should work fine without a caching dir. Your 403 error is because your authentication setup isn't working properly.
Should I be looking into https://github.com/Azure/Microsoft365R/blob/master/inst/app_registration.md? I'm not familiar with app registrations. Is this done in Azure Active Directory or on sharepoint?
App registrations are an AAD thing, not Sharepoint. Basically you need to tell Azure about your Shiny app: what permissions it needs, who is allowed to use it (anyone with a Microsoft account, or only people in your org), any secure credentials required, etc.
If this is the first time you're dealing with app regs, start here: https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-overview
There are vignettes scattered across AzureAuth, AzureGraph and Microsoft365R that also have relevant information: https://cran.r-project.org/web/packages/AzureAuth/vignettes/scenarios.html https://cran.r-project.org/web/packages/AzureGraph/vignettes/auth.html https://cran.r-project.org/web/packages/Microsoft365R/vignettes/auth.html
Creating a new app registration usually involves going to the Azure portal or using the CLI. As a first point of contact, you should talk to a sysadmin in your org. If you're still having problems, shoot me an email.
Ok. Thanks. I'm going to look into this with IT next week and will let you know.
No luck so far. IT is looking into this. When trying locally, I get following:
I would say that is not a problem in the app registration, or is it?
You need to supply the ID of your app registration in the create_graph_login()
call. If you don't do this, it will use a default app ID which doesn't have the required permissions to read Sharepoint sites and drives.
If you use Microsoft365R, by default it will supply its own app ID which has these permissions. However, this ID won't work for a Shinyapps.io app; you'll have to create your own. See the links posted above; in addition, AzureAuth has a Shiny vignette that you should also read.
The overall process is like this:
Use it in the call to get_azure_token
, which for a Shiny app has to be split into 2 parts:
# in ui.R -- see AzureAuth Shiny vignette
auth_uri <- build_authorization_uri(c("https://graph.microsoft.com/.default", "openid", "offline_access"),
tenant="yourtenant", app="yourappid", redirect_uri="https://your.shiny.site")
redir_js <- sprintf("location.replace(\"%s\");", auth_uri)
tags$script(HTML(redir_js))
# in server.R
opts <- parseQueryString(isolate(session$clientData$url_search))
token <- get_azure_token(c("https://graph.microsoft.com/.default", "openid", "offline_access"),
tenant="yourtenant", app="yourappid", authorize_args=list(redirect_uri="https://your.shiny.site"),
auth_type="authorization_code",
authcode=opts$code)
gr <- AzureGraph::ms_graph$new(token=token)
site <- gr$get_sharepoint_site()
drv <- site$get_drive()
When I try using c("https://graph.microsoft.com/.default", "openid", "offline_access")
I am getting errors.
There are different types of errors with differing code:
# in ui.R -- see AzureAuth Shiny vignette
auth_uri <- build_authorization_uri(c("https://graph.microsoft.com/.default", "openid", "offline_access"),
tenant="yourtenant", app="yourappid", redirect_uri="https://your.shiny.site")
redir_js <- sprintf("location.replace(\"%s\");", auth_uri)
tags$script(HTML(redir_js))
# in server.R
opts <- parseQueryString(isolate(session$clientData$url_search))
token <- get_azure_token(c("https://graph.microsoft.com/.default", "openid", "offline_access"),
tenant="yourtenant", app="yourappid", authorize_args=list(redirect_uri="https://your.shiny.site"),
auth_type="authorization_code",
authcode=opts$code)
gr <- AzureGraph::ms_graph$new(token=token)
site <- gr$get_sharepoint_site(site_url = "yoursharepointsiteurl")
drv <- site$get_drive()
Gives following error:
Warning: Error in get_azure_token: unused argument (authcode = opts$code)
Error in get_azure_token(c("https://graph.microsoft.com/.default", "openid", :
unused argument (authcode = opts$code)
That might be because the app registration uses a secret. So I change the get_azure_token
to:
token <- get_azure_token(resource = c("https://graph.microsoft.com/.default", "openid", "offline_access"),
tenant = "yourtenant",
app = "yourappid",
auth_type = "authorization_code",
authorize_args = list(redirect_uri="https://your.shiny.site"),
use_cache = FALSE,
auth_code = opts$code,
password = "yoursecret")
The error changes to:
Error : Resource for Azure Active Directory v1.0 token must be a single string
When I change the get_azure_token
to:
token <- get_azure_token(resource = c("https://graph.microsoft.com/.default"),
tenant = "yourtenant",
app = "yourappid",
auth_type = "authorization_code",
authorize_args = list(redirect_uri="https://your.shiny.site"),
use_cache = FALSE,
auth_code = opts$code,
password = "yoursecret")
I get following error:
Warning: Error in process_response: Unauthorized (HTTP 401). Failed to complete operation. Message:
Access token validation failure. Invalid audience.
Error in process_response(res, match.arg(http_status_handler), simplify) :
Unauthorized (HTTP 401).
I am guessing this is caused by the build_authorization_uri
. So I changed that:
auth_uri <- build_authorization_uri(c("https://graph.microsoft.com/.default"),
tenant="yourtenant", app="yourappid", authorize_args=list(redirect_uri="https://your.shiny.site"),
But then I cannot complete the login. Part of the url I seeing says: invalid_resource
.
So I leave the .default
out. Which makes it the code I was already using.
This is:
# in ui.R -- see AzureAuth Shiny vignette
auth_uri <- build_authorization_uri("https://graph.microsoft.com/",
tenant="yourtenant", app="yourappid", redirect_uri="https://your.shiny.site")
redir_js <- sprintf("location.replace(\"%s\");", auth_uri)
tags$script(HTML(redir_js))
# in server.R
opts <- parseQueryString(isolate(session$clientData$url_search))
token <-token <- get_azure_token(resource = "https://graph.microsoft.com/",
tenant = "yourtenant",
app = "yourappid",
auth_type = "authorization_code",
authorize_args = list(redirect_uri="https://your.shiny.site"),
use_cache = FALSE,
auth_code = opts$code,
password = "yoursecret")
gr <- AzureGraph::ms_graph$new(token=token)
site <- gr$get_sharepoint_site(site_url = "yoursharepointsiteurl")
drv <- site$get_drive()
Which takes me back to the error I was already getting:
Warning: Error in process_response: Forbidden (HTTP 403). Failed to complete operation. Message:
Error in process_response(res, match.arg(http_status_handler), simplify) :
Access denied.
All this makes me think that the step:
get_azure_token(*, version=2)
to specify an AAD v2 tokenRegardless, this isn't the place for debugging random user code, and there doesn't seem to be any problem with Microsoft365R here. You may want to ask on Stackoverflow or the RStudio community forums for help. If you're still unable to make progress, as mentioned before, send me an email.
Draft vignette here: https://github.com/Azure/Microsoft365R/blob/shiny-auth/vignettes/shiny.Rmd
I am trying to develop a shiny app (which is hosted on shinyapps.io). The data resides on a company sharepoint site. To authenticate users I am following allong the Authenticating from Shiny vignette. This works when I use resource <- "https://graph.microsoft.com" instead of resource <- "https://management.azure.com". I get a token, but am at a loss how to use this to connect to the sharepoint site (to retrieve the data (rds-files) from there).
Is this possible? If so, how?