I am trying to connect to sharepoint to load excel files within an unattended R script using the package Microsoft365R
I have created the app within Azure, and assigned it permissions. I have been able to successfully connect to a users onedrive and list the files within it.
Code that works
library(AzureGraph)
library(Microsoft365R)
tenant <- "your-tenant-here"
# the application/client ID of the app registration you created in AAD
# - not to be confused with the 'object ID' or 'service principal ID'
app <- "your-app-id-here"
# retrieve the client secret (password) from an environment variable
pwd <- Sys.getenv("EXAMPLE_MS365R_CLIENT_SECRET")
# retrieve the user whose OneDrive we want to access
# - this should be their 'userPrincipalName', which is of the form 'name#tenant.com'
# - note this may be different to their regular email address
user <- Sys.getenv("EXAMPLE_MS365R_TARGET_USER")
# create a Microsoft Graph login
gr <- create_graph_login(tenant, app, password=pwd, auth_type="client_credentials")
drv <- gr$get_user(user)$get_drive()
drv$list_files()
When running the below code, i get the error
# the application/client ID of the app registration to use
app <- "your-app-id-here"
# get the service account username and password
user <- Sys.getenv("EXAMPLE_MS365R_SERVICE_USER")
pwd <- Sys.getenv("EXAMPLE_MS365R_SERVICE_PASSWORD")
# SharePoint site and path to folder
sitename <- Sys.getenv("EXAMPLE_MS365R_SPO_SITENAME")
folderpath <- Sys.getenv("EXAMPLE_MS365R_SPO_FOLDERPATH")
# use the 'resource_owner' auth type for a non-interactive login
site <- get_sharepoint_site(sitename, tenant=tenant, app=app, username=user, password=pwd,
auth_type="resource_owner")
Output:
Error in process_aad_response(res) :
Unauthorized (HTTP 401). Failed to obtain Azure Active Directory token. Message:
AADSTS7000218: The request body must contain the following parameter: 'client_assertion' or 'client_secret'.
The function doesn't appear to have an argument for client secret.
I have followed the vignettes within the package, but i must be missing something. Is anyone able to provide assistance?
Resource
https://cran.r-project.org/web/packages/Microsoft365R/vignettes/scripted.html
You will get the AADSTS7000218 error when you try to get an authentication token for an application with the "Web" platform configuration without the client_secret parameter.
How about when the platform configuration of the application to Mobile and desktop applications ?
To change the platform configuration:
Open the application from App registrations page on Azure AD, and open Manage - Authentication page.
Delete the existing Web platform configuration.
Open Add a platform and select Mobile and desktop applications.
Related
I tried to start working the "tuber" package. A tutorial on how to use this package can be found here: https://www.r-bloggers.com/using-the-tuber-package-to-analyse-a-youtube-channel/
Now I've set up OAuth 2.0 client in my google developer account (web client). However when i try to log in with my details like this:
user <- my_user_name
key <- my_key
yt_oauth(my_user_name, my_key, token = '')
I get the following error:
The redirect URI in the request, urn:ietf:wg:oauth:2.0:oob, can only be used by a Client ID for native application. It is not allowed for the WEB client type. You can create a Client ID for native application at https://console.developers.google.com/apis/credentials/oauthclient
When creating your OAuth client ID, set http://localhost:1410/ as Authorized redirect URIs. You may need to edit and update your existing client ID.
I'm building an Azure web app for a client that will be provisioned into many other directories for their customers. This app will call a web API in my client's directory, which will then call back to another web API in the customer's directory. Something like this:
Other Customer AAD1 --------- My client AAD2
App --------------------------------> Web API 2
Web API 1 <-------------------------- Web API 2
We have been able to get the first call to work. This requires a corresponding App Registation for Web API 2 in AAD1. We figure that we could get the callback to work by following the same pattern, with a registration for Web API1 in AAD2. However, that might be a LOT of these 'proxy' registration in my client's AAD, so we're looking at alternatives.
We are exploring using Managed Service Identity, which we think will allow us to get tokens that are valid for resources in other tenants. If there's a better way, I'm certainly interested in knowing about it.
I've followed the code example from here using the Microsoft.Azure.Services.AppAuthentication library: https://learn.microsoft.com/en-us/azure/app-service/app-service-managed-service-identity#obtaining-tokens-for-azure-resources
// In Web API 2
using Microsoft.Azure.Services.AppAuthentication;
// ...
var azureServiceTokenProvider = new AzureServiceTokenProvider();
string accessToken = await azureServiceTokenProvider.GetAccessTokenAsync(
"https://<App ID URI for Web API1>");
Web API2 is configured to have a Managed Service Identity.
I'm currently running this on my local machine, and I've installed Azure CLI and I'm logged in. I've tried 'az account get-access-token', and I get a valid token.
When Web API2 tries to get the token to be able to call Web API1, I get an exception:
Parameters: Connectionstring: [No connection string specified], Resource: , Authority: . Exception Message: Tried the following 2 methods to get an access token, but none of them worked.
Parameters: Connectionstring: [No connection string specified], Resource: , Authority: . Exception Message: Tried to get token using Managed Service Identity. Unable to connect to the Managed Service Identity (MSI) endpoint. Please check that you are running on an Azure resource that has MSI setup.
Parameters: Connectionstring: [No connection string specified], Resource: , Authority: . Exception Message: Tried to get token using Azure CLI. Access token could not be acquired. ERROR: Get Token request returned http error: 400 and server response: {"error":"invalid_grant","error_description":"AADSTS65001: The user or administrator has not consented to use the application with ID '04b07795-8ddb-461a-bbee-02f9e1bf7b46' named 'Web API 1'. Send an interactive authorization request for this user and resource.\r\nTrace ID: f5bb0d4d-6f92-4fdd-81b7-e82a78720a00\r\nCorrelation ID: 04f92114-8d9d-40c6-b292-965168d6a919\r\nTimestamp: 2017-10-19 16:39:22Z","error_codes":[65001],"timestamp":"2017-10-19 16:39:22Z","trace_id":"f5bb0d4d-6f92-4fdd-81b7-e82a78720a00","correlation_id":"04f92114-8d9d-40c6-b292-965168d6a919"}
What's interesting is that there's no application with ID '04b07795-8ddb-461a-bbee-02f9e1bf7b46' in either AAD1 or AAD2. Is this a known Azure app? I thought that it might be the Service Management API, but I'm not sure.
In any case, I'm not sure of the proper way to grant permission. I've tried building different content URLs like this into my browser, but none of them seem to have done the trick:
https://login.microsoftonline.com/(AAD1 ID)/adminconsent
?client_id=(App ID)
&redirect_uri=https://localhost:44341
&resource=(App ID URI for Web API1)
&prompt=admin_consent
https://login.microsoftonline.com/(AAD1 ID)/adminconsent
?client_id=04b07795-8ddb-461a-bbee-02f9e1bf7b46
&redirect_uri=https://localhost:44341
&resource=(App ID URI for Web API1)
&prompt=admin_consent
(This last one tells me that the reply URL is incorrect; since it's not one of my apps, I can't find the reply URL)
Note that the tenant is AAD1.
Am I missing something, or am I not using this feature correctly?
Thanks in advance.
AzureServiceTokenProvider uses Azure CLI (among other options) for local development. For a scenario where a service calls an Azure Service, this works using the developer identity from Azure CLI, since Azure services allow access to both users and applications.
For a scenario where a service calls another custom service (like your scenario), you need to use a service principal for local development. For this, you have two options:
Login to Azure CLI using a service principal.
First, create a service principal for local development
https://learn.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli?view=azure-cli-latest
Then login to Azure CLI using it.
az login --service-principal -u 25922285-eab9-4262-ba61-8083533a929b --password <<pwd>> --tenant 72f988bf-86f1-41af-91ab-2d7cd011db47 --allow-no-subscriptions
Use the --allow-no-subscriptions argument since this service principal may not have access to any subscription.
Now, AzureServiceTokenProvider will get a token using this service principal for local development.
Specify service principal details in an environment variable. AzureServiceTokenProvider will use the specified service principal for local development. Please see the section Running the application using a service principal in local development environment in this sample on how to do that. https://github.com/Azure-Samples/app-service-msi-keyvault-dotnet
Note: Ths is only for local development. AzureServiceTokenProvider will use MSI when deployed to App Service.
can't seem to find the info.
Let's say your shiny app's url is : "joe.shinyapps.io/great_app"
I'm looking to get that url from within that shiny app (running on shinyapps.io).
That way, the redirect URI I use for oauth could change dynamically based on which shiny app account I deployed the app to...
Thanks for any help
I found the answer while researching packages that do use user credentials oauth and shiny (those packages must use a redirect URI that is specific to the user's app). The following bit is taken from GoogleAuthR package.
if(!is.null(session)){
pathname <- session$clientData$url_pathname
hostname <- session$clientData$url_hostname
port <- session$clientData$url_port
url <- paste0(session$clientData$url_protocol,
"//",
hostname,
if(port != "") paste0(":", port),
if(pathname != "/") pathname)
RStudio Server authentication with libpam-pwdfile
I'm developing a Vagrant box with a full analytic stackand this includes, ofc, a RStudio Server instance.
I decided to use this pam module https://github.com/tiwe-de/libpam-pwdfile as it allows to authenticate against a pwd file. This allows me to let users access to RStudio without the need to make them server users.
But I'm not able to authenticate at all!
I've added these two files to my setup:
/etc/rstudio/passwd
jdoe:s/NKv5DK33kxQ
(the password was made using mkpasswd using crypt)
/etc/pam.d/rstudio
auth required pam_pwdfile.so pwdfile=/etc/rstudio/passwd
account required pam_permit.so
session required pam_permit.so
password required pam_deny.so
When I perform a pamtester --verbose rstudio jdoe authenticate as the user rstudio-server I get authentication successful.
But still not able to login to RStudio.
Looking into /var/lof/auth.log I can see that some lines:
PAM unable to dlopen(pam_permit.so#015): /lib/security/pam_permit.so#015: cannot open shared object file: No such file or directory
PAM adding faulty module: pam_permit.so#015
PAM unable to dlopen(pam_deny.so#015): /lib/security/pam_deny.so#015: cannot open shared object file: No such file or directory
PAM adding faulty module: pam_deny.so#015
This happens when I insert a valid user (with both the right or a wrong password).
Only if I insert a fake user at login screen I get an additional line pam_pwdfile(rstudio:auth): user not found in password database.
I'm totally puzzled why these files are not found: they are not /lib/security but in /lib/x86_64-linux-gnu/security/ actually.
Is it because of these missing files I cannot login?
I have a Shiny application that uses the Instagram API, and needs an access token. When running locally, I am able to use
full_url <-oauth_callback()
full_url <- gsub("(.*localhost:[0-9]{1,5}/).*", x=full_url, replacement="\\1")
print(full_url)
to get the callback url to register with Instagram. How would I go about getting this url when my application is deployed?
Additionally, and this might be related, when the app is deployed I get an error that:
Error : oauth_listener() needs an interactive environment
I never explicitly use oauth_listener(), so I'm not sure how to counteract this. All of my oauth related code is as follows:
instagram <- oauth_endpoint(
authorize="https://api.instagram.com/oauth/authorize",
access="https://api.instagram.com/oauth/access_token",)
my_app <- oauth_app(app_name, client_id, client_secret)
ig_oauth <- oauth2.0_token(instagram, my_app, scope="basic", type="application/x-www-form-urlencoded", cache=FALSE)